Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

✨ Write cleaner, conciser, and more consistent SwiftUI code with a suite of pre-made extensions, view modifiers, and components.

License

Notifications You must be signed in to change notification settings

Flowductive/shiny-swift-ui

Repository files navigation

Social Preview

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!

GitHub release (latest SemVer) GitHub Release Date GitHub issues GitHub pull requests

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().onAppear {
 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()

Hover tooltip modifier (macOS)

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()

About

✨ Write cleaner, conciser, and more consistent SwiftUI code with a suite of pre-made extensions, view modifiers, and components.

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

AltStyle によって変換されたページ (->オリジナル) /