My understanding of SwiftUI
- The main advantage of SwiftUI over UIKit is to write both your initial UI rendering as well as any updates to your UI in one go.
- On a very abstract level, this is similar to TEA, but practically, it's quite different: updates in SwiftUI are incremental, and for many things there's no diffing necessary.
In SwiftUI, you define your views as structs that conform to View
. The View
protocol has a single requirement: you need to implement body
, a computed property that returns another type conforming to View
.
Just like normal structs in Swift, you can use properties anywhere inside your View
. However, unlike normal structs, some properties are special. Specifically, properties that are defined using the property wrappers EnvironmentObject
, ObjectBinding
, State
(and some others). When SwiftUI renders the body, it will subscribe to these properties. When these properties change, they send a notification, and SwiftUI will re-render the necessary parts. I call these special properties "sources of truth".
There's another type called Binding
. A Binding<Foo>
contains two things: a way to get a value of type Foo
, and a way to set a value of type Foo
. A binding isn't a source of truth: there's no way for SwiftUI to subscribe to a binding, or to know (directly) that its value changed. Instead, a binding is typically derived from a source of truth. When SwiftUI sets a value through a binding, the source of truth is changed, and this causes the re-render.
-
TODO: difference between List(someCollection) and List { ForEach(someCollection) }.
-
TODO: source of truth / bindings & UIViewRepresentable