NavigationLink doesn't work with new .searchable modifier on SwiftUI 3.0

Viewed 509

I'm trying the new features of SwiftUI 3.0 introduced at Apple WWDC21.

In particular I'm trying to use the .searchable modifier to implement a search bar in a list and let the user navigate to the Item view from the search result using a NavigationLink.

struct OrderItem : Identifiable {
    let id = UUID()
    var label : String
    var value : Bool = false
}

struct BindingTest: View {
    @State var items = [OrderItem(label: "Shirts"), OrderItem(label: "Pants"), OrderItem(label: "Socks")]
    @State private var searchedText = ""
    
    @ViewBuilder
    var body: some View {
        
        NavigationView {
            
            List($items) { $item in
                NavigationLink(destination: ItemView(item: $item)) {
                    HStack {
                        if(item.value) {
                            Image(systemName: "star.fill").foregroundColor(.yellow)
                        }
                        Text(item.label)
                    }
                }
            }.navigationBarTitle("Clothing")
            
            // Search bar
                .searchable(text: $searchedText, placement: .automatic) {
                    if searchedText != "" {
                        
                        // Search result
                        ForEach($items.filter({$0.label.wrappedValue.contains(searchedText)})) { $item in
                            
                            NavigationLink(destination: ItemView(item: $item)) {
                                HStack {
                                    if(item.value) {
                                        Image(systemName: "star.fill").foregroundColor(.yellow)
                                    }
                                    Text(item.label)
                                }
                            }.searchCompletion(item.label)
                            
                        }
                    }
                }
            
        }
    }
}

But when I'm in the search result list and I tap on one result, the NavigationLink doesn't work and it shows me the original list. Anyone else experiencing this issue?

I can't upload a video but this is the search result view, as I said when I tap on one result the NavigationLink doesn't work

[EDIT] I checked this NavigationLink inside .searchable does not work but unfortunately it doesn't answer my question because my NavigationLink is already inside a NavigationView.

1 Answers

You have two Navigation Links here, one inside your original content, and one passed as a closure to your searchable modifier, which is actually being shown as the searchText changes. The latter isn't inside a Navigation View, and hence is unable to navigate to the second screen. To achieve your expectation, you should have the ForEach with the NavigationLink in the original content itself, and filter the list, based on the search text.

The search completion is supposed to be a guidance to complete the searchText, not to navigate to the second screen.

The updated code should look something like this

struct BindingTest: View {
@State var items = [OrderItem(label: "Shirts"), OrderItem(label: "Pants"), OrderItem(label: "Socks")]
@State private var searchedText = ""

@ViewBuilder
var body: some View {
    NavigationView {
        List($items.filter({$0.label.wrappedValue.contains(searchedText)})) { $item in
            NavigationLink(destination: ItemView(item: $item)) {
                HStack {
                    if(item.value) {
                        Image(systemName: "star.fill").foregroundColor(.yellow)
                    }
                    Text(item.label)
                }
            }
        }
        .searchable(text: $searchedText, placement: .automatic) {
            if searchedText != "" {
                ForEach($items.filter({$0.label.wrappedValue.contains(searchedText)})) { $item in
                    Text(item.label).searchCompletion(item.label)
                }
            }
        }
    }
}

}

Hope it answers your question :)

Related