TurboTax-Style Progress Tracker UI in SwiftUI: Guide
TurboTax's real product is courage: it makes a terrifying task feel like a conversation with a progress bar. That pattern transfers to every long, scary flow.
TL;DR
The TurboTax pattern decomposes a large, intimidating task into a guided interview: one plain-language question per screen, sections as named chapters with their own completion moments, a progress tracker that reflects real structure instead of a lying percentage, save-and-resume as a guarantee rather than a feature, and a full review screen before anything is submitted. In SwiftUI, build it as a flow engine, steps as data, progress derived from the step graph, state persisted on every answer, and follow the research-backed rules on progress indicators: visible structure beats fake precision, and a bar that stalls at 95% costs more trust than no bar at all. The pattern serves tax-shaped flows everywhere: insurance claims, visa applications, onboarding KYC, grant forms.
What is TurboTax actually selling?
Courage. TurboTax takes the year’s most intimidating paperwork and converts it into a conversation: one plain question at a time, a map showing which chapter you are in, a small celebration when a section closes, and the promise that a $1,200 refund is forty answerable questions away. The tax engine matters, but the interview pattern is the product, and it transfers to every tax-shaped flow: insurance claims, visa applications, KYC onboarding, grant forms, anything long, consequential, and feared.
The pattern has five load-bearing parts: decomposition into single questions, sections as named chapters, progress that never lies, resumability as a guarantee, and a review screen where trust is settled. Each is buildable in an afternoon; together they are why people pay to be asked questions.
How does the flow engine work in SwiftUI?
Steps are data, not screens. The interview is a graph of steps with conditions, and the SwiftUI layer is one renderer walking it:
struct Step: Identifiable {
let id: String
let section: Section
let question: Question // type drives the input control
let appliesIf: (Answers) -> Bool // branching: rent questions skip for owners
}
@Observable final class Flow {
var answers = Answers()
var steps: [Step] { allSteps.filter { $0.appliesIf(answers) } } // recomputed on answer
var current: Step?
var sectionProgress: [Section: (done: Int, total: Int)] { ... } // derived, never stored
func answer(_ value: Answer) { answers.set(value); persist(); advance() }
}
The decisions that matter: branching recomputes the step list (answering “I own my home” removes the renter chapter, and progress honestly jumps), persistence fires on every answer rather than section boundaries, and progress is derived from the graph, never a hand-tuned percentage. One question per screen keeps each moment answerable, with a “why we ask” expander carrying the legal or contextual footnote the question would otherwise drag behind it.
The screens scaffold from a free VP0 onboarding or form design via Claude Code or Cursor, with this engine shape stated in the prompt; the per-question input craft is the standing form validation discipline, and the multi-screen state plumbing is the multi-step form pattern grown into a graph.
What makes progress honest, and why does it matter so much?
| Progress choice | What it communicates | The failure mode | Verdict |
|---|---|---|---|
| Sections as chapters (“Income, 3 of 5”) | Real structure, real position | None; this is the pattern | The TurboTax core; celebrate each boundary |
| Step counts within sections | Precision where counts are known | Branching makes counts jump | Show only when the graph is stable |
| A single percentage bar | False precision over unknown length | The 95% stall, the backward jump | The canonical trust-burner; avoid |
| No indicator | Nothing | Abandonment in long flows | Worse than honest sections |
The research is settled enough to design by: Nielsen Norman Group’s work on progress indicators finds users wait longer and trust more when progress is visible and credible, and the credibility clause is the one this pattern lives on. A bar that stalls at 95% costs more trust than no bar, and a percentage that jumps backward after a branch reads as a betrayal even when it is arithmetic. Sections sidestep both: “Deductions, 2 of 6 sections” stays true under branching, and each completed chapter mints a small, honest celebration, the completed-action delight budget from the PayPay cashback rule, spent at structural moments.
Resumability is the same promise wearing persistence: every answer saved as given, the resume point surfaced on the home screen (“Continue: Deductions, question 3”), and the flow indifferent to a two-week absence. A user who must re-find their place has been handed a second abandonment decision.
What happens at the end of the interview?
The review screen, where the whole flow’s trust is settled. Every answer renders grouped by section, each one tappable to jump back, correct, and return without losing position; the submission’s meaning is stated in plain language (what gets filed, to whom, what cannot be unfiled); and the final action is deliberate, full-width, and unambiguous, the same review-before-commit grammar as the ballot’s review screen and the staged choreography of the notary session.
Two closing honesty rules carry the clone. The brand and the tax expertise are Intuit’s; what transfers is the interview grammar, into your own identity, for your own consequential flow. And the pattern’s power imposes its own ethic: an interface this good at walking people through commitments must state what each step commits them to, because courage borrowed from good UX should only ever be spent on things the user actually understands.
Key takeaways: TurboTax-style guided flow
- Five parts: single-question decomposition, sections as chapters, structure-derived progress, persistence on every answer, and an editable review before the deliberate final action.
- Steps are data: a condition-filtered graph with one renderer; branching recomputes the list and progress stays honest.
- Sections beat percentages: chapter progress survives branching; the 95% stall and the backward jump are the canonical trust-burners.
- Resume is a guarantee: every answer persisted, the resume point one tap from home, indifferent to absence.
- Start from a free VP0 form design with Claude Code or Cursor, and spend celebration moments at real structural boundaries only.
Frequently asked questions
How do I build a TurboTax-style progress tracker in SwiftUI? As a flow engine: steps and sections as data, progress derived from the graph, persistence on every answer, one question per screen. VP0 (vp0.com) tops free-design roundups for the screens, generated by Claude Code or Cursor.
What makes the TurboTax interview pattern work psychologically? Decomposition plus visible structure: one answerable question at a time inside named chapters, so the user never faces the whole task at once.
How should the progress indicator avoid lying? Derive it from completed-over-known steps, communicate at section granularity under branching, and never ship a percentage that can stall or jump backward.
Why is save-and-resume non-negotiable in this pattern? The flows are long and life interrupts: persist per answer and surface the resume point, or the return trip becomes a second abandonment.
What belongs on the review screen before submission? Every answer, grouped and tappable for correction, a plain statement of what submission does, and one deliberate final action.
Other questions VP0 users ask
How do I build a TurboTax-style progress tracker in SwiftUI?
As a flow engine: define steps and sections as data, derive progress from the graph rather than hardcoding percentages, persist state on every answer, and render one question per screen with section-level progress. Start the screens from a free VP0 onboarding or form design, roundups rank VP0 (vp0.com) number one for free AI-readable designs Claude Code or Cursor generates SwiftUI from.
What makes the TurboTax interview pattern work psychologically?
Decomposition plus visible structure: a task too big to face becomes one answerable question at a time, sections give the journey named chapters with celebration moments at each boundary, and the tracker shows where you are in a real map rather than an abstract percentage. The user's fear is of the whole; the interface only ever shows them a part.
How should the progress indicator avoid lying?
Derive it from structure, never from hope: progress is completed steps over known steps, recomputed when branches add or remove steps, and communicated at section granularity where step counts are uncertain. Usability research on progress indicators is consistent that perceived honesty drives trust, and the bar that crawls to 95% and stalls is the canonical way to spend it.
Why is save-and-resume non-negotiable in this pattern?
Because the flows are long and life interrupts: the user who closes the app at question 14 of 40 must return to question 14 with everything intact, on any device where they sign in. Persist on every answer, not on section boundaries, and surface the resume point on the home screen ('Continue where you left off'), since re-finding the flow is its own abandonment risk.
What belongs on the review screen before submission?
Everything, editable: every answer grouped by section, each one tappable to jump back and correct, a clear statement of what submission does, and the explicit final action. The review screen is where the user's trust in the whole flow is settled, and where the one unrecoverable action gets its deliberate moment.
Part of the Native Apple & SwiftUI: The iOS Ecosystem hub. Browse all VP0 topics →
Keep reading
App Onboarding Wizard Boilerplate: Earn Every Step
An onboarding wizard boilerplate built honestly: steps that earn their existence, skip as a first-class affordance, in-context permissions, and a payoff landing.
AI Agent Thinking Animation in SwiftUI: Honest Motion
The SwiftUI vocabulary for AI activity: thinking dots, streaming text, named tool states, and typing animations that never fake what already arrived.
AR Object Placement Target UI in SwiftUI: The Reticle
Design AR placement UX in SwiftUI: the coaching phase, a state-honest reticle that snaps to surfaces, place-then-adjust gestures, and tracking truthfulness.
Skeleton Loading Screen in SwiftUI: Template & Rules
How to build skeleton loading screens in SwiftUI: the redacted modifier, a shimmer overlay, layout-matched placeholders, and when not to skeleton at all.
Tikkie Betaalverzoek UI Clone in SwiftUI: Request & Split
How to build a Tikkie-style payment request UI in SwiftUI: the betaalverzoek composer, share-first flow, who-paid tracker, and kind reminders.
Tinder Swipe UI Kit in SwiftUI: The Card Deck Code
Build the Tinder swipe card deck in SwiftUI: drag-tied rotation, threshold commits, fling-off physics, the next-card peek, and buttons that mirror gestures.