SwiftUI Fundamentals
Prerequisites: Structs, Closures, Opaque and existential types
SwiftUI is Apple's framework for building user interfaces on every Apple platform. It's declarative: you describe what the interface should look like for the current data, and SwiftUI works out how to draw it and update it when the data changes. SwiftUI requires Xcode on a Mac.
A first view
Create a new iOS App project in Xcode, and ContentView.swift
looks like this:
import SwiftUI
struct ContentView: View {
var body: some View {
VStack(spacing: 12) {
Image(systemName: "swift")
.font(.largeTitle)
.foregroundStyle(.orange)
Text("Hello, SwiftUI!")
.font(.title)
.bold()
Text("Views are just structs.")
.foregroundStyle(.secondary)
}
.padding()
}
}
#Preview {
ContentView()
}
- A view is a struct conforming to
View, with abodythat returns other views. VStackarranges views vertically;HStackhorizontally;ZStacklayers them on top of each other.- Modifiers such as
.font(...)and.padding()return a new, modified view. Order matters:.padding().background(.yellow)puts the color behind the padding; the reverse order doesn't. #Previewshows the view live in Xcode's canvas as you type.Image(systemName:)uses SF Symbols, Apple's library of thousands of icons.
Lists and navigation
import SwiftUI
struct Language: Identifiable {
let id = UUID()
let name: String
let year: Int
}
struct LanguageList: View {
let languages = [
Language(name: "Swift", year: 2014),
Language(name: "Kotlin", year: 2011),
Language(name: "Rust", year: 2010),
]
var body: some View {
NavigationStack {
List(languages) { language in
NavigationLink(language.name) {
Text("\(language.name) appeared in \(language.year)")
.navigationTitle(language.name)
}
}
.navigationTitle("Languages")
}
}
}
List needs to tell rows apart, so the data conforms to
Identifiable (it has a unique id). NavigationStack and
NavigationLink provide the familiar push-to-detail navigation.
Why views are structs
SwiftUI creates and discards view structs constantly — every time data
changes, body is re-evaluated. That's cheap, because views are small
value types describing the UI, not the heavyweight on-screen objects
themselves. Keep body fast and free of side effects: no network
calls or heavy computation inside it.
Accessibility comes built in
Standard SwiftUI controls work with VoiceOver, Dynamic Type (the user's
preferred text size), and Dark Mode automatically. Use semantic fonts
like .title and .body rather than fixed point sizes, and add
.accessibilityLabel(...) to icon-only buttons.