You are viewing a free preview of this lesson.
Subscribe to unlock all 10 lessons in this course and every other course on LearningBro.
SwiftUI is Apple's declarative framework for building user interfaces across all Apple platforms. This lesson covers the fundamentals of SwiftUI: views, modifiers, state management, layout, lists, and navigation.
SwiftUI is a declarative UI framework introduced at WWDC 2019. Instead of describing step-by-step how to build a UI (imperative), you declare what the UI should look like for a given state:
| Aspect | UIKit (Imperative) | SwiftUI (Declarative) |
|---|---|---|
| Approach | Describe steps to build UI | Describe what UI should look like |
| State changes | Manually update views | Automatic re-rendering |
| Layout | Auto Layout constraints | Declarative stacks and modifiers |
| Platforms | iOS/macOS specific | All Apple platforms |
| Preview | Run on simulator | Live preview in Xcode |
import SwiftUI
struct ContentView: View {
var body: some View {
Text("Hello, SwiftUI!")
.font(.title)
.foregroundStyle(.blue)
.padding()
}
}
Every SwiftUI view conforms to the View protocol and has a body property that returns some View.
Modifiers transform views and return new views:
Text("Welcome")
.font(.largeTitle)
.fontWeight(.bold)
.foregroundStyle(.primary)
.padding()
.background(.blue.opacity(0.1))
.cornerRadius(10)
| Modifier | Purpose |
|---|---|
.font() | Set the text style |
.foregroundStyle() | Set the foreground colour |
.padding() | Add spacing around the view |
.background() | Add a background |
.frame() | Set explicit size |
.cornerRadius() | Round corners |
.shadow() | Add drop shadow |
.opacity() | Set transparency |
SwiftUI uses stacks for layout:
// Horizontal stack
HStack(spacing: 16) {
Image(systemName: "star.fill")
.foregroundStyle(.yellow)
Text("Favourite")
Spacer()
Text("5 items")
.foregroundStyle(.secondary)
}
.padding()
// Vertical stack
VStack(alignment: .leading, spacing: 8) {
Text("Title")
.font(.headline)
Text("Subtitle")
.font(.subheadline)
.foregroundStyle(.secondary)
}
// Depth stack (layers)
ZStack {
Color.blue
Text("Overlay")
.foregroundStyle(.white)
.font(.title)
}
For simple local state within a view:
struct CounterView: View {
@State private var count = 0
var body: some View {
VStack(spacing: 20) {
Text("Count: \(count)")
.font(.title)
HStack(spacing: 16) {
Button("Decrement") { count -= 1 }
Button("Increment") { count += 1 }
}
}
.padding()
}
}
Pass mutable state to child views:
struct ToggleRow: View {
let title: String
@Binding var isOn: Bool
var body: some View {
Toggle(title, isOn: $isOn)
}
}
struct SettingsView: View {
@State private var notifications = true
@State private var darkMode = false
var body: some View {
VStack {
ToggleRow(title: "Notifications", isOn: $notifications)
ToggleRow(title: "Dark Mode", isOn: $darkMode)
}
.padding()
}
}
For shared observable state:
@Observable
class UserSettings {
var username = ""
var isLoggedIn = false
var theme = "Light"
}
struct ProfileView: View {
var settings: UserSettings
Subscribe to continue reading
Get full access to this lesson and all 10 lessons in this course.