Activity 1
Build an adaptive summary card
Create a card with a title, optional subtitle, progress value, and action. Test narrow width and an accessibility text size.
Hint: Avoid fixed heights and allow the text column to grow.
SwiftUI Fundamentals
Reason about SwiftUI's proposal-based layout system and build adaptive interfaces with stacks, grids, frames, and safe areas.
Before you begin
Learning stage
SwiftUI layout is a negotiation. A parent proposes a size to each child, the child chooses a size that fits its own rules, and the parent positions the returned sizes. A frame does not usually force a child to redraw at an arbitrary size; it participates in that negotiation and can wrap the child with minimum, ideal, or maximum constraints.
HStack, VStack, and ZStack arrange views horizontally, vertically, and in depth. Lazy stacks and grids delay creation for large scrolling content. Alignment guides coordinate meaningful edges, while Spacer consumes flexible space. Prefer flexible relationships over fixed screen dimensions.
Adaptive layout must survive small devices, split views, localization, and larger accessibility text. Let text wrap, use layoutPriority only when content importance justifies it, and choose alternatives such as ViewThatFits when genuinely different arrangements are needed.
Learning stage
The card uses flexible width and semantic alignment without depending on one device size.
import SwiftUI
struct ProgressCard: View {
let title: String
let completed: Int
let total: Int
var body: some View {
HStack(alignment: .firstTextBaseline, spacing: 16) {
VStack(alignment: .leading, spacing: 6) {
Text(title)
.font(.headline)
.fixedSize(horizontal: false, vertical: true)
Text("Keep learning at your pace")
.font(.subheadline)
.foregroundStyle(.secondary)
}
.frame(maxWidth: .infinity, alignment: .leading)
Text("(completed)/(total)")
.font(.title3.monospacedDigit().bold())
.accessibilityLabel("(completed) of (total) complete")
}
.padding()
.background(.thinMaterial, in: .rect(cornerRadius: 18))
}
}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 card with a title, optional subtitle, progress value, and action. Test narrow width and an accessibility text size.
Hint: Avoid fixed heights and allow the text column to grow.
Activity 2
Display feature tiles in a LazyVGrid that automatically changes column count based on available width.
Hint: Use an adaptive GridItem with a meaningful minimum width.
Learning stage
Answer each question before revealing the explanation.
QUESTION 1
A parent proposes a size to a child
The child then chooses a size under its rules and the parent positions it.
QUESTION 2
Text can require more space after localization or Dynamic Type changes, causing clipping or overlap.
Flexible vertical sizing lets content remain readable across user and device contexts.
Learning stage
Explain the design in terms of data flow, identity, lifecycle, platform behavior, and trade-offs.
Short answer: Parents propose sizes, children choose fitting sizes, and parents position the results.
Each container participates in a proposal–response process. Modifiers such as frame wrap a view and adjust the proposals or reported size. This explains why a maxWidth frame, fixedSize, layoutPriority, and GeometryReader have different effects and why reading only the screen width is usually the wrong model.
Possible follow-ups
Learning stage
SwiftUI layout is a cooperative negotiation, not a collection of absolute coordinates. Use semantic containers, flexible constraints, and representative accessibility and localization tests.