Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does one use NavigationLink isActive binding when working with List in SwiftUI?

The use case is pretty simple. I have a List of places, and each corresponds to a geofence. I need to enable navigation in that particular row(s) whose geofence the user is inside. And the list is dynamic and is fetched from an API. There are similar question on Stackoverflow, but those address only static lists.

I tried using a dictionary of bools, but I am not able to make it work.

This is a simplified mock code:

struct ListView: View {
  @State private var navActive: [UUID: Bool] = [:]
  var body: some View {
    
           List (viewModel.allItems, id: \.id) { item in
           NavigationLink(destination: DetailView(item), isActive: $navActive[item.id]) {
             Text(item.name)
             .onTapGesture {
                if currentLocation.isInside(item.geofence) { navActive[item.id] = true }
             }
         }
      }
   }
}

I get this error: Cannot convert value of type 'Binding<Bool?>' to expected argument type 'Binding<Bool>' on the NavigationLink isActive argument.

Note: I've populated the navActive dictionary with key-value pairs on receiving allItems with an onRecieve modifier

like image 326
Aswath Avatar asked Dec 30 '22 22:12

Aswath


1 Answers

Here is a possible approach for your use-case

struct ListView: View {
    
    // ... your view model defined here

    @State private var selectedItem: UUID? = nil
    var body: some View {

        List (viewModel.allItems, id: \.id) { item in
            Text(item.name)
                .onTapGesture {
                    self.selectedItem = item.id
                }
                .background(
                    NavigationLink(destination: DetailView(item), tag: item.id,
                        selection: $selectedItem) { EmptyView() }
                        .buttonStyle(PlainButtonStyle())
                )
        }
    }
}
like image 170
Asperi Avatar answered Jan 05 '23 17:01

Asperi