Conforming to View requires exactly one thing: a body property returning some View, describing the UI declaratively rather than imperatively creating and mutating UIKit objects the way the older Apple UI framework required. @State marks a property as local, view-owned mutable state; SwiftUI automatically re-evaluates (redraws) any view reading that state the moment it changes, with no manual UI-update code needed at all — conceptually the same declarative model as Jetpack Compose in Kotlin. The two were revealed within a month of each other in 2019 -- Compose's first developer preview was announced at Google I/O in May, SwiftUI at WWDC in June -- but SwiftUI reached a stable, production-ready 1.0 that same September, while Compose didn't reach its stable 1.0 until July 2021. One shared SwiftUI codebase can target iOS, macOS, watchOS, and tvOS.
A basic View
body simply describes what the view looks like — there's no imperative "create a label, set its text" code anywhere, just a declaration of the desired result.
struct Greeting: View {
let name: String
var body: some View {
Text("Hello, \(name)!")
}
}@State: local mutable state, automatic UI updates
Tapping the button changes count; SwiftUI automatically re-evaluates body since it reads that state — no manual "update the label" code anywhere, exactly the same mental model as Compose's recomposition.
struct Counter: View {
@State private var count = 0
var body: some View {
VStack {
Text("Count: \(count)")
Button("Increment") {
count += 1
}
}
}
}ViewBuilder: what makes the nested syntax work
VStack's trailing closure is actually a @ViewBuilder-powered result builder — the same underlying mechanism (a Swift language feature, not SwiftUI-specific magic) that lets multiple views be listed one after another and combined into a single view hierarchy.
VStack { // VStack's initializer takes a @ViewBuilder closure
Text("First")
Text("Second")
Text("Third")
} // all three Texts are combined automatically by the result builder