Pattern · Forms

New

Step Form SwiftUI Block

A multi-step form container: a step indicator, your view per step, Back and Continue, Review with Edit, and Submit.

A container for forms that take several steps, such as a booking or a new project. Each step is your own view with a validity flag, so Continue waits until it's complete, and steps slide in from the side they come from. Review sums up the answers each step reports with Edit links that jump back, and Submit shows working, done and failed.

  • SwiftUI
  • iOS 17.0+
  • step-form
Get SwiftPieces Pro

$199 once, every piece included. See how installing works · Sign in

01

What's included

SwiftUI source you own, built on Apple frameworks only.

  • Segments with "Step 2 of 4" and the step's name
  • Your own view per step, with Continue waiting until it's valid
  • Steps that slide in from their side, or fade with Reduce Motion
  • Review built from each step's answers, with Edit links that jump back
  • Submit with working, done and failed, then a settled sent state

02

Implementation notes

How it behaves, what it handles, and the decisions behind it.

Above the card, "Step 2 of 4" and the step's name sit over a row of segments that fill in ink as the form moves on. The card holds the current step, your own view, and steps slide in from the side they come from, or fade with Reduce Motion. Continue stays dimmed until the step reports itself valid; Back appears from the second step. The last step is Review, built from the answers each step reports: a group per step with its title, its answers as label and value, "Not given" for an empty one, and an Edit link that jumps back to it, after which Continue reads "Back to review" and returns straight there. A note can close Review. On Review the button carries your submit title and runs your closure: a spinner, then a check that stays as the form settles as sent, with the Edit links and Back gone; a thrown error's message shows under it.

Notes

  • StepForm(steps:current:reviewTitle:reviewNote:submitTitle:onSubmit:onSuccess:). Only steps and onSubmit are required. It is a section: no navigation stack, background, padding or scroll view of its own, so place it in your own column or sheet.
  • A StepForm.Step is an id, a title for the indicator and Review, isValid, a summary of StepForm.Answers (.init("When", "Tuesday, Oct 28, 11:00")) and a @ViewBuilder content closure with your view. Build the steps in your body from your own state, so validity and answers stay current as the person edits. Your views own their fields and bindings; the block owns the order, the indicator and the buttons.
  • current is a Binding<Int> for the step showing, from 0, with steps.count meaning Review. Leave it out and the block keeps it.
  • onSubmit sends the answers you already hold. Return to succeed, throw to fail; a thrown LocalizedError's errorDescription shows under the button, otherwise "Couldn't send this. Try again." A CancellationError goes back to rest quietly. onSuccess is called once the check has shown; move on there.
  • If a step turns invalid after Review (an answer cleared through Edit), Review marks it "Not finished" and Submit takes the person to it.
  • reviewTitle defaults to "Review", submitTitle to "Submit". reviewNote is a footnote on a quiet panel under the answers, such as what happens next.
  • Haptics: a selection tick as the step changes, success when it's sent, an error when it fails.
  • VoiceOver reads the indicator as one header ("Step 2 of 4, Day and time"), announces each step as it arrives and the result, reads each answer as one element and each Edit link as "Edit Day and time", and hints at a dimmed Continue. At accessibility sizes Back and Continue stack and answers place their values under their labels.
  • Reduce Motion turns the slides into fades.
  • StepFormExample at the end of StepForm.swift is the Book a consultation screen from the preview, opened from the studio's Website page so Website is chosen to start: a service list, day and time chips for the next five weekdays, the person's details already filled from their account, and Review with a note about the calendar invite. Booking takes a moment. It reads the theme from the environment; pass wrapsInNavigationStack: false to push it in your own stack.

Theming

  • Reads SPTheme from @Environment(\.spTheme) and requires the design-system item.
  • The step's name uses the display face (type.face) at 20 points, capped at semibold; "Step 2 of 4" is type.footnote in textSecondary. Segments are 4 point capsules in textPrimary when reached and fill ahead.
  • The card is color.surface with radius.lg and 16 point padding, clipped so steps slide inside it; the indicator, card and buttons sit 24 points apart.
  • Review groups are type.headline titles with type.subhead answers, labels in textSecondary and values in textPrimary (textTertiary for "Not given"), divided by SPHairline. Edit is type.subhead semibold in textPrimary. The note sits on fill at radius.sm in type.footnote.
  • Continue and Submit are accent with accentOn in type.headline, radius.md, 52 points, at 40% opacity until the step is valid; Back is the secondary button on fill with textPrimary.
  • Steps move with motion.smooth, states with motion.snappy, presses with motion.standard.