Activity 1
Build a bound stepper
Create a parent that owns a study-minute goal and a child editor that receives a Binding<Int>. Derive a progress label from the value.
Hint: The child should not create another State copy of the goal.
SwiftUI Fundamentals
Model local source-of-truth state, pass writable projections with Binding, and preserve predictable one-way data flow.
Before you begin
Learning stage
A SwiftUI interface changes when its data changes. State marks local, private source-of-truth data that SwiftUI stores for a view's stable identity. The property wrapper connects mutations to view invalidation; the View struct itself remains a lightweight value.
Binding is not a second copy of a value. It is a readable and writable projection into state owned elsewhere. A parent can pass $property to a child that needs to edit that value while ownership remains clear. If a child only displays the value, pass the value itself instead.
Store the minimum source of truth. Calculate derived values such as isFormValid from their inputs rather than synchronizing another state property. Lift state to the nearest common owner when multiple children must coordinate, but avoid moving purely local interaction state into a global model.
Learning stage
The parent owns the draft name, while the focused editor receives a binding and reports save intent separately.
import SwiftUI
struct ProfileScreen: View {
@State private var draftName = "Mina"
@State private var savedMessage: String?
var body: some View {
Form {
NameEditor(name: $draftName)
Button("Save") {
savedMessage = "Saved (draftName.trimmingCharacters(in: .whitespaces))"
}
.disabled(draftName.trimmingCharacters(in: .whitespaces).isEmpty)
if let savedMessage { Text(savedMessage).foregroundStyle(.secondary) }
}
}
}
struct NameEditor: View {
@Binding var name: String
var body: some View {
TextField("Display name", text: $name)
}
}Learning stage
Connect the SwiftUI concept to complete, maintainable application features.
Learning stage
Identify patterns that weaken ownership, identity, adaptation, accessibility, or user experience.
Learning stage
Build the behavior in a small Xcode project and review it in multiple states.
Activity 1
Create a parent that owns a study-minute goal and a child editor that receives a Binding<Int>. Derive a progress label from the value.
Hint: The child should not create another State copy of the goal.
Activity 2
Replace isLoading, hasError, and isEmpty flags with one enum and render each valid screen state with switch.
Hint: Include associated data for content and failure messages.
Learning stage
Answer each question before revealing the explanation.
QUESTION 1
Read-write access to a value owned elsewhere
A binding keeps one source of truth while allowing a child or control to edit it.
QUESTION 2
No. It should usually be derived from the current field values.
Storing derivable state creates synchronization paths and possible contradictions.
Learning stage
Explain the design in terms of data flow, identity, lifecycle, platform behavior, and trade-offs.
Short answer: Place the source of truth at the nearest stable owner that needs to coordinate every consumer and editor.
Keep private interaction state local. If multiple siblings need the same value, lift it to their parent. Shared feature data may belong to an observable model. Pass immutable values to readers and bindings to editors. Avoid duplicating state or storing values that can be computed.
Possible follow-ups
Learning stage
Predictable SwiftUI begins with explicit ownership. State owns local truth, Binding edits truth owned elsewhere, and derived values remain computations rather than additional synchronized storage.