.png)
SwiftUI extensions and components that just make sense.
📦 Lightweight, Swift-y looking code for modern SwiftUI developers
⚙️ Dozens of view modifiers to add expected functionality
💨 Custom, built-in transitions & animations for views
💻 Cross-platform Support for iOS, macOS, watchOS
🧩 Pre-made components that look great in any app
💕 This package works great with and is inspired by SwiftUIX!
🚧 Wiki under construction. Read below to get started!


What is ShinySwiftUI?
ShinySwiftUI aims to turn messy Swift + SwiftUI code into cleaner, Swift-ier code. It also aims to provide a library of useful modifiers, components, and extensions to create consistent, good-looking apps.
// 😴 Before
HStack {
ViewA()
ViewB()
}
// ✨ After
ViewA() + ViewB()
// 😴 Before
MyView().frame(width: 30.0, height: 30.0)
MyView().frame(maxWidth: 40.0, maxHeight: 40.0)
// ✨ After
MyView().frame(30.0)
MyView().frame(max: 40.0)
// 😴 Before
MyView().onAppear {
UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
}
// ✨ After
MyView().hideKeyboard()
// 😴 Before
MyView().overlay(RoundedRectangle(cornerRadius: 5.0).stroke(.red, lineWidth: 2.0))
// ✨ After
MyView().roundedBorder(.red, cornerRadius: 5.0, lineWidth: 2.0)
Completed Features
- App Layout
- Pre-defined spacing values →
- Layout using Generic Stack →
- Layout using Shove View →
- Fixed-width spacers →
- View Functionality
- Operations on views →
- View frame modifiers →
- View refresh modifier →
- View styling modifiers →
- View timing modifiers →
- Custom animation/transitions →
- Debugging view modifier →
- Screenshot view method →
- Hover tooltip modifier (macOS) →
- View mouse position checking (macOS) →
- Other Features
- Image modifiers
- Color features →
- Quick dividers
- Visual effects →
- Pre-made buttons
- Action item highlight modifier
Most of the above features are cross-platform and are supported on both iOS and macOS.
Get Started
Add ShinySwiftUI to your project using Swift Package Manager:
https://github.com/Flowductive/shiny-swift-ui
📐 App Layout Features
Pre-defined spacing values
Improve code consistency with CGFloat
spacing values:
MyView().padding(.m).cornerRadius(.xs)
These values include: .xxs
, .xs
, .s
, .m
, .l
. .xl
, and .xxl
.
Layout using Generic Stack
You can use a generic stack, or GStack
, to position items vertically or horizontally using a Bool
input:
GStack(platform == .iOS ? .vertical : .horizontal) {
MyViewA()
MyViewB()
}
A typical use case of GStack
is for changing display layout on macOS vs. iOS devices.
Layout using Shove View
Use a ShoveView
to quickly push inner content to one side/corner:
// Position MyView right
ShoveView(.trailing) {
MyView()
}
// Position MyView top-left
ShoveView(.topLeading) {
MyView()
}
Fixed-width spacers
Use fixed-width spacers for consistent spacing:
// Large vertical spacer
Spacer.VL
// Extra-small vertical spacer
Spacer.HXS
Vertical spacer variants include .VXXS
, .VXS
, .VS
, .VM
, .VL
, .VXL
, and .VXXL
.
Horizontal spacer variants include .HXXS
, .HXS
, .HS
, .HM
, .HL
, .HXL
, and .HXXL
.
⚙️ View Functionality
Operations on views
You can quickly group views using operators:
// Horizontal stack
MyViewA() + MyViewB()
// Vertical stack, center-aligned
MyViewA() / MyViewB()
// Vertical stack, left-aligned
MyViewA() /- MyViewB();
View frame modifiers
Easily set the dimensions of a square frame:
// Sets MyView's frame to width = 30.0, height = 30.0
MyView().frame(30.0)
Stretch the view:
// Stretch horizontally
MyViewA().stretchH()
// Stretch vertically
MyViewB().stretchV()
// Stretch in both directions
MyViewC().stretch()
View refresh modifier
Use a @State
boolean to refresh a view quickly:
@State var refresh: Bool = false
var body {
MyView().refreshable(with: refresh)
}
Updating the view would require that refresh.toggle()
is called.
View styling modifiers
Set the relative opacity of a view:
MyView().opacity(.half)
You can choose from (in order of opacity) .opaque
, .most
, .half
, .quarter
, .almostInvisible
, .invisible
.
Add a rounded border to any view:
MyViewA().roundedBorder(.green)
MyViewB().roundedBorder(.red, cornerRadius: .s, lineWidth: 2.0)
View timing modifiers
Repeat an action in a specified interval:
MyView().every(3.0) {
print("Hello") // Runs every 3 seconds
}
Perform an action after a specified delay:
MyView().after(3.0) {
print("Hello") // Runs 3 seconds after the view appears
}
Custom animation/transitions
Add a slick transition to a view using .slickAnimation(value:)
:
MyViewA().slickAnimation()
MyViewB().slickAnimation(value: myVal)
Add a custom built-in animation; i.e. .slickEaseOut
, .slickEaseIn
, .rampEaseOut
, .rampEaseIn
, .bounce
, .lightBounce
, or .page
:
MyViewA().animation(.rampEaseOut)
MyViewB().animation(.slickEaseOut(duration: 1.0), value: myVal)
Add a custom built-in transition; i.e. .turn
, .swipe
, .pop
:
MyViewA().transition(.turn)
Debugging view modifier
Use the .debug()
view modifier to randomly change the background color of the view for debugging:
MyView().debug()
Screenshot view method
Take a screenshot of a view and save the image to path:
myView.snapshot()
Add a tooltip upon hover to a view:
MyView()
.withTooltip(present: $showTooltip) {
Text("This is a tooltip!")
}
Add a keyboard shortcut, which automatically adds the shortcut tooltip:
MyViewA().shortcut("c", modifiers: [.shift, .command])
MyViewB().shortcut(.defaultAction)
View mouse position checking (macOS)
Track the relative position of the mouse pointer within the view:
MyView().trackingMouse { pos in
// ...
}
🎁 Other Features
Color features
Take advantage of color utilities:
// Init color from hex code
var color = Color(hex: "#ffffff")
// If bindingBool.wrappedValue is true, show the color
MyView().foregroundColor(.red.if($bindingBool))
// Get a lighter version of a color
lighter = color.ligher(by: 0.3)
// Colors also have relative opacities, just like views
halfColor = color.opacity(.half)
When importing ShinySwiftUI, colors will also conform to Codable
.
Visual effects
Easily add SwiftUI wraps of UIVisualEffectView
:
VisualEffectView()
SwiftUI extensions and components that just make sense.
📦 Lightweight, Swift-y looking code for modern SwiftUI developers
⚙️ Dozens of view modifiers to add expected functionality
💨 Custom, built-in transitions & animations for views
💻 Cross-platform Support for iOS, macOS, watchOS
🧩 Pre-made components that look great in any app
💕 This package works great with and is inspired by SwiftUIX!
🚧 Wiki under construction. Read below to get started!
What is ShinySwiftUI?
ShinySwiftUI aims to turn messy Swift + SwiftUI code into cleaner, Swift-ier code. It also aims to provide a library of useful modifiers, components, and extensions to create consistent, good-looking apps.
Completed Features
Most of the above features are cross-platform and are supported on both iOS and macOS.
Get Started
Add ShinySwiftUI to your project using Swift Package Manager:
📐 App Layout Features
Pre-defined spacing values
Improve code consistency with
CGFloat
spacing values:These values include:
.xxs
,.xs
,.s
,.m
,.l
..xl
, and.xxl
.Layout using Generic Stack
You can use a generic stack, or
GStack
, to position items vertically or horizontally using aBool
input:A typical use case of
GStack
is for changing display layout on macOS vs. iOS devices.Layout using Shove View
Use a
ShoveView
to quickly push inner content to one side/corner:Fixed-width spacers
Use fixed-width spacers for consistent spacing:
Vertical spacer variants include
.VXXS
,.VXS
,.VS
,.VM
,.VL
,.VXL
, and.VXXL
. Horizontal spacer variants include.HXXS
,.HXS
,.HS
,.HM
,.HL
,.HXL
, and.HXXL
.⚙️ View Functionality
Operations on views
You can quickly group views using operators:
View frame modifiers
Easily set the dimensions of a square frame:
Stretch the view:
View refresh modifier
Use a
@State
boolean to refresh a view quickly:Updating the view would require that
refresh.toggle()
is called.View styling modifiers
Set the relative opacity of a view:
You can choose from (in order of opacity)
.opaque
,.most
,.half
,.quarter
,.almostInvisible
,.invisible
.Add a rounded border to any view:
View timing modifiers
Repeat an action in a specified interval:
Perform an action after a specified delay:
Custom animation/transitions
Add a slick transition to a view using
.slickAnimation(value:)
:Add a custom built-in animation; i.e.
.slickEaseOut
,.slickEaseIn
,.rampEaseOut
,.rampEaseIn
,.bounce
,.lightBounce
, or.page
:Add a custom built-in transition; i.e.
.turn
,.swipe
,.pop
:Debugging view modifier
Use the
.debug()
view modifier to randomly change the background color of the view for debugging:Screenshot view method
Take a screenshot of a view and save the image to path:
Hover tooltip modifier (macOS)
Add a tooltip upon hover to a view:
Add a keyboard shortcut, which automatically adds the shortcut tooltip:
View mouse position checking (macOS)
Track the relative position of the mouse pointer within the view:
🎁 Other Features
Color features
Take advantage of color utilities:
When importing ShinySwiftUI, colors will also conform to
Codable
.Visual effects
Easily add SwiftUI wraps of
UIVisualEffectView
: