Search code examples
ioslistswiftuiswiftui-navigationlinkvstack

SwitUI - Two navigationLink in a list


I have two NavigationLink in a cell of my List

I want to go to destination1 when I tap once,and go to destination2 when I tap twice. So I added two tap gesture to control the navigation.

But when I tap,there are two questions:

  • 1 The tap gesture block won't be called.
  • 2 The two navigation link will be both activated automatically even if they are behind a TextView. The real effect is: Tap the cell -> go to Destination1-> back to home -> go to Destination2 -> back to home

Here is my code :

struct MultiNavLink: View {
    @State var mb_isActive1 = false;
    @State var mb_isActive2 = false;
    
    var body: some View {
        return
            NavigationView {
                List {
                    ZStack {
                        NavigationLink("", destination: Text("Destination1"), isActive: $mb_isActive1)
                        NavigationLink("", destination: Text("Destination2"), isActive: $mb_isActive2)
                        Text("Single tap::go to destination1\nDouble tap,go to destination2")
                    }
                    .onTapGesture(count: 2, perform: {()->Void in
                        NSLog("Double tap::to destination2")
                        self.mb_isActive2 = true
                    }).onTapGesture(count: 1, perform: {()->Void in
                        NSLog("Single tap::to destination1")
                        self.mb_isActive1 = true
                    })
                }.navigationBarTitle("MultiNavLink",displayMode: .inline)
        }
    }
}

I have tried remove the List element,then everything goes as I expected. It seems to be the List element that makes everything strange.

I found this question:SwiftUI - Two buttons in a List,but the situation is different from me.

I am expecting for your answer,thank you very much...


Solution

  • Try the following approach - the idea is to hide links in background of visible content and make them inactive for UI, but activated programmatically.

    Tested with Xcode 12 / iOS 14.

    struct MultiNavLink: View {
    
        var body: some View {
            return
                NavigationView {
                    List {
                        OneRowView()
                    }.navigationBarTitle("MultiNavLink", displayMode: .inline)
            }
        }
    }
    
    struct OneRowView: View {
        @State var mb_isActive1 = false
        @State var mb_isActive2 = false
    
        var body: some View {
            ZStack {
                Text("Single tap::go to destination1\nDouble tap,go to destination2")
            }
            .frame(maxWidth: .infinity, maxHeight: .infinity)
            .contentShape(Rectangle())
            .background(Group {
                NavigationLink(destination: Text("Destination1"), isActive: $mb_isActive1) {
                        EmptyView() }
                    .buttonStyle(PlainButtonStyle())
                NavigationLink(destination: Text("Destination2"), isActive: $mb_isActive2) {
                        EmptyView() }
                    .buttonStyle(PlainButtonStyle())
            }.disabled(true))
            .highPriorityGesture(TapGesture(count: 2).onEnded {
                self.mb_isActive2 = true
            })
            .onTapGesture(count: 1) {
                self.mb_isActive1 = true
            }
        }
    }