With following code:
struct HomeView: View {
var body: some View {
NavigationView {
List(dataTypes) { dataType in
NavigationLink(destination: AnotherView()) {
HomeViewRow(dataType: dataType)
}
}
}
}
}
What's weird, when HomeView
appears, NavigationLink
immediately loads the AnotherView
. As a result, all AnotherView
dependencies are loaded as well, even though it's not visible on the screen yet. The user has to click on the row to make it appear.
My AnotherView
contains a DataSource
, where various things happen. The issue is that whole DataSource
is loaded at this point, including some timers etc.
Am I doing something wrong..? How to handle it in such way, that AnotherView
gets loaded once the user presses on that HomeViewRow
?
Update:
This code will be for iOS 15 and below.
The best way I have found to combat this issue is by using a Lazy View.
struct NavigationLazyView<Content: View>: View {
let build: () -> Content
init(_ build: @autoclosure @escaping () -> Content) {
self.build = build
}
var body: Content {
build()
}
}
Then the NavigationLink would look like this. You would place the View you want to be displayed inside ()
NavigationLink(destination: NavigationLazyView(DetailView(data: DataModel))) { Text("Item") }
For iOS 16 and above use NavigationStack:
var body: some View {
NavigationStack {
List(items) { item in
NavigationLink(item.name, value: item)
}
.navigationDestination(for: DataModel.self) { item in
DetailView(data: item)
}
.navigationTitle("Items")
}
}