Buttons and controls · 5 free pieces

SwiftUI buttons and controls

Custom SwiftUI buttons with press depth, loading and success states, press-and-hold confirmation, plus a timer dial and a gesture-driven avatar stack.

All components

About these pieces

One self-contained Swift file each, Apple frameworks only, from iOS 17.

A button is the one control people touch most, so it is where missing detail shows. Elastic Button is a ButtonStyle that squashes toward the touch point, rubber-bands when dragged and springs back. Commit Button runs an async action through one phase: a capsule collapses into a spinner, then blooms into a success check, or shakes into an error that doubles as retry. Hold to Confirm guards destructive actions with a fill that sweeps while held, milestone haptics and a rewind on early release.

Timer Dial is a countdown ring you set by dragging its knob, with a tick per step and a heavier detent every five seconds. Fan Stack spreads overlapping avatars apart and lets a drag scrub across them to pick one.

Learn the technique: SwiftUI buttons guide, SwiftUI haptics guide.

Questions

How the pieces work, and how to build the same thing yourself. Every piece's page has its full notes.

How do I make a custom button style in SwiftUI?

Conform to ButtonStyle and read configuration.isPressed in makeBody to change scale, color or shadow while pressed, animated with a spring. Apply it with .buttonStyle(YourStyle()). Elastic Button is a ready-made ButtonStyle that adds touch-point squash and drag stretch.

How do I show a loading state in a SwiftUI button?

Model the action as a phase (idle, loading, success, error), disable the button while loading, and swap the label for a ProgressView. Commit Button does this with one animated shape and returns to idle on its own.

How do I add haptics to a SwiftUI button?

On iOS 17 and later use .sensoryFeedback(.impact, trigger: value) on the button, where the trigger changes on tap. Every control here already fires the right feedback at the right moment.

Next

Ready to build something better?

55 pieces, one file each, yours to keep. Start with the library or see what the whole app looks like.