Member-only story
Lazy NavigationLink for SwiftUI
We don’t want to preload every ViewModel!
Difficulty: Beginner | Easy | Normal | Challenging
This article has been developed using Xcode 11.7, and Swift 5.2.4
You want to display some content in a `List`. You place a breakpoint and…well there is a nasty surprise.
Read on!
Prerequisites:
- You will be expected to make a Single View SwiftUI Application] in Swift.
Terminology:
- SwiftUI: A simple way to build user interfaces Across Apple platforms
The motivation
The destination views for navigation links are created when the body for the List
is updated — and therefore raises the individual view models.
How did this situation occur?
The code
I’ve rather lazily (on topic for this article!) called the initial view ContentView.swift
. Sorry for that.
This means that we create the SwiftUI
view and feed it a view model in the SceneDelegate
file.
let viewModel = ContentViewModel()
// Create the SwiftUI view that provides the window contents.
let contentView = ContentView(viewModel: viewModel)
// Use a UIHostingController as window root view controller.
if let windowScene = scene as? UIWindowScene {
let window = UIWindow(windowScene: windowScene)
window.rootViewController = UIHostingController(rootView: contentView)
self.window = window
window.makeKeyAndVisible()
}
and the content view takes us to a DetailView
by displaying information from a view model in a List
.
struct ContentView: View {
@ObservedObject var viewModel: ContentViewModel
init(viewModel: ContentViewModel) {
self.viewModel = viewModel
}
var body: some View {
NavigationView {
List {
ForEach(viewModel.animals, id: \.self) {
animal in
NavigationLink(
destination:
DetailView(viewModel: DetailViewModel(text: animal))
) {…