Skip to content
AgileLogics
7 min read

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 a body that returns other views.
  • VStack arranges views vertically; HStack horizontally; ZStack layers 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.
  • #Preview shows 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.