1

I want to press a cell of List to display a menu then click the menu push to a new view by NavigationLink.

enter image description here

Here is my code:

import SwiftUI

struct ContentView: View {
    let array = ["a", "b"]

    @State var isPushed: Bool = false

    @State var isDisplayMenu: Bool = false
    @State var isDestination1Clicked: Bool = false
    var body: some View {
        NavigationView {
            List {
                ForEach(array, id:\.self) { value in
                    VStack {
                        RowView(title: value)
                         .frame(maxWidth: .infinity)
                        if isDisplayMenu {
                            HStack {
                                ZStack {
                                    Text("D1")
                                    NavigationLink(
                                        destination: Destination1(),
                                        label: {
                                            EmptyView()}).hidden()
                                }

                                ZStack {
                                    Text("D2")
                                    NavigationLink(
                                        destination: Destination2(),
                                        label: {
                                            EmptyView()}).hidden()
                                }
                            }

                        }
                    }
                    .background(Color.green)
                    .contentShape(Rectangle())
                    .onTapGesture(count: 1, perform: {
                        isDisplayMenu.toggle()
                    })
                }
            }
        }

    }
}

struct Destination1: View {
    var body: some View {
        Text("D1")
    }
}

struct Destination2: View {
    var body: some View {
        Text("D2")
    }
}

struct RowView: View {

    var title: String

    var body: some View {
        VStack {
            Text("title")
            Text(title)
        }.background(Color.red)
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

When click the cell the D1 and D2 was displayed. But the NavigationLink doesn't work.

I think the reason is onTapGesture blocked it. How can I make the NavigationLink works?

Any help? thanks!

William Hu
  • 15,423
  • 11
  • 100
  • 121
  • Since " Suggested edit queue is full" I will add my suggestion as a comment here... It is better you can ask , How to use more than one NavigationLink in a same List cell. – YodagamaHeshan Nov 12 '20 at 03:15
  • @Yodagama thanks, I'm trying to use two `Button` control `isActive` of one `NavigationLink`, not sure it helps, just cost two long on this issue. If I can't make it work I will choose your approach,. – William Hu Nov 12 '20 at 03:24
  • yes you can go to that approach, somehow you can use one NavigationLink active at a time in List cell. – YodagamaHeshan Nov 12 '20 at 03:40
  • Does this answer your question https://stackoverflow.com/a/63497954/12299030 or https://stackoverflow.com/a/63197406/12299030? – Asperi Nov 12 '20 at 04:16
  • @Yodagama yes, but you can control the destination ` destination: isDestination1Clicked ? AnyView(Destination1()) : AnyView(Destination2())` – William Hu Nov 12 '20 at 04:26

2 Answers2

1

There are some restriction defined in List to be just a List itself.

So that we cannot use more than one NavigationLink inside a List cell ( If we use more than one , we cannot get expected behaviour)

And also Empty views does not get touch events.

Here is the fixes for your code.

struct ContentView: View {
    let array = ["a", "b"]
    
    @State var isPushed: Bool = false
    
    @State var isDisplayMenu: Bool = true
    @State var isDestination1Clicked: Bool = false
    var body: some View {
        NavigationView {
            ScrollView {
                ForEach(array, id:\.self) { value in
                    VStack {
                        RowView(title: value)
                            .frame(maxWidth: .infinity)
                            .background(Color.green)
                            .onTapGesture(count: 1, perform: {
                                withAnimation {
                                    isDisplayMenu.toggle()
                                }
                            })
                        
                        if isDisplayMenu {
                            HStack {
                                
                                NavigationLink(
                                    destination: Destination1(),
                                    label: {
                                        Spacer()
                                        Text("D1")
                                            .foregroundColor(.black)
                                        Spacer()
                                    })
                                
                                NavigationLink(
                                    destination: Destination2(),
                                    label: {
                                        Spacer()
                                        Text("D2")
                                        Spacer()
                                    })
                                    .foregroundColor(.black)
                                
                            }
                            .background(Color.purple)
                            
                        }
                    }
                    .padding()
                    .contentShape(Rectangle())
                    
                }
            }
        }
        
    }
}

struct Destination1: View {
    var body: some View {
        Text("D1")
    }
}

struct Destination2: View {
    var body: some View {
        Text("D2")
    }
}

struct RowView: View {
    
    var title: String
    
    var body: some View {
        VStack {
            Text("title")
            Text(title)
        }.background(Color.red)
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}
YodagamaHeshan
  • 4,996
  • 2
  • 26
  • 36
0

try to attach the "onTapGesture" to the "NavigationView".

NavigationView {
  ....
 }.onTapGesture(count: 1, perform: {
        isDisplayMenu.toggle()
 })