I wrote an app known as SwiftUI View Lifecycle. The app permits you to observe how totally different SwiftUI constructs and containers have an effect on a view’s lifecycle, together with the lifetime of its state and when
onAppear will get known as. The code for the app is on GitHub. It may be constructed for iOS and macOS.
Once we write SwiftUI code, we assemble a view tree that consists of nested view values. Cases of the view tree are ephemeral: SwiftUI consistently destroys and recreates (components of) the view tree because it processes state modifications.
The view tree serves as a blueprint from which SwiftUI creates a second tree, which represents the precise view “objects” which might be “on display screen” at any given time. (The “objects” could possibly be precise
NSView objects, but additionally different representations. The precise which means of “on display screen” can range relying on context.) Chris Eidhof likes to name this second tree the render tree (the hyperlink factors to a 3 minute video the place Chris demonstrates this duality, extremely beneficial).
The render tree persists throughout state modifications and is utilized by SwiftUI to ascertain view identification. When a state change causes a change in a view’s worth, SwiftUI will discover the corresponding view object within the render tree and replace it in place, quite than recreating a brand new view object from scratch. That is in fact key to creating SwiftUI environment friendly, however the render tree has one other vital perform: it controls the lifetimes of views and their state.
We will outline a view’s lifetime because the timespan it exists within the render tree. The lifetime begins with the insertion into the render tree and ends with the elimination. Importantly, the lifetime extends to view state outlined with
@StateObject: when a view will get faraway from the render tree, its state is misplaced; when the view will get inserted once more later, the state can be recreated with its preliminary worth.
The SwiftUI View Lifecycle app tracks three lifecycle occasions for a view and shows them as timestamps:
- @State = when the view’s state was created (equal to the beginning of the view’s lifetime)
- onAppear = when
onAppearwas final known as
- onDisappear = when
onDisappearwas final known as
The app permits you to observe these occasions in several contexts. As you click on your approach by the assorted examples, you’ll discover that the timing of those occasions modifications relying on the context a view is embedded in. For instance:
elseassertion creates and destroys its little one views each time the situation modifications; state will not be preserved.
ScrollVieweagerly inserts all of its kids into the render tree, no matter whether or not they’re contained in the viewport or not. All kids seem straight away and by no means disappear.
Listingwith dynamic content material (utilizing
ForEach) lazily inserts solely the kid views which might be presently seen. However as soon as a toddler view’s lifetime has began, the checklist will hold its state alive even when it will get scrolled offscreen once more.
onDisappearget known as repeatedly as views are scroll into and out of the viewport.
- A NavigationStack calls
onDisappearas views are pushed and popped. State for mother or father ranges within the stack is preserved when a toddler view is pushed.
TabViewbegins the lifetime of all little one views straight away, even the non-visible tabs.
onDisappearget known as repeatedly because the consumer switches tabs, however the tab view retains the state alive for all tabs.
Listed here are just a few classes to remove from this:
- Completely different container views could have totally different efficiency and reminiscence utilization behaviors, relying on how lengthy they hold little one views alive.
onAppearisn’t essentially known as when the state is created. It will probably occur later (however by no means earlier).
onAppearmay be known as a number of instances in some container views. For those who want a facet impact to occur precisely as soon as in a view’s lifetime, contemplate writing your self a
onFirstAppearhelper, as proven by Ian Eager and Jordan Morgan in Operating Code Solely As soon as in SwiftUI (2022-11-01).
I’m certain you’ll discover extra fascinating tidbits once you play with the app. Suggestions is welcome!