[SOLVED] A generics problem whilst creating a lazy NavigationLink in SwiftUI

Issue

I noticed that when using NavigationLinks in SwiftUI, the destination views are loaded before they are presented, which causes an issue in my application.

I used the answer here to solve this problem creating a NavigationLazyView as follows:

struct NavigationLazyView<Content: View>: View {
    let build: () -> Content
    init(_ build: @autoclosure @escaping () -> Content) {
        self.build = build
    }
    var body: Content {
        build()
    }
}

and I use it like this in my views:

struct ViewA: View {
    var body: some View {
        NavigationLink(destination: NavigationLazyView(ViewB())){
            Text(text: "Click me")
        }  
    }
}

I tried to go a step further, and create a lazy version of a navigation link:

struct NavigationLazyLink<Content1 : View, Content2 : View> : View {
   
    let destination : () -> Content1;
    let viewBuilder : () -> Content2;
    
    var body: some View {
        NavigationLink(destination: NavigationLazyView(destination())){
            viewBuilder()
        }
    }
}

However when I try to use NavigationLazyLink like this:

struct ViewA: View {
    var body: some View {
        NavigationLazyLink(destination: ViewB()){
            Text(text: "Click me")
        }  
    }
}

I get the following errors:

  • Cannot convert value of type 'ViewB' to expected argument type '() -> Content1'
  • Generic parameter 'Content1' could not be inferred
  • Explicitly specify the generic arguments to fix this issue

I can’t quite get by head around the problem and I have a feeling I have misunderstood how to use generic types

Solution

This is because destination is a closure:

let destination : () -> Content1

So you need to pass ViewB as a closure:

NavigationLazyLink(destination: { ViewB() }) {
    Text("Click me")
}

Answered By – pawello2222

Answer Checked By – Willingham (BugsFixing Volunteer)

Leave a Reply

Your email address will not be published. Required fields are marked *