SwiftUI onTapGesture 块 NavigationLink 动作

Posted

技术标签:

【中文标题】SwiftUI onTapGesture 块 NavigationLink 动作【英文标题】:SwiftUI onTapGesture block NavigationLink action 【发布时间】:2020-11-12 01:41:47 【问题描述】:

我想按List 的一个单元格显示一个菜单,然后单击NavigationLink 的菜单推送到一个新视图。

这是我的代码:

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()
    

单击单元格时会显示 D1 和 D2。但是NavigationLink 不起作用。

我认为原因是onTapGesture 阻止了它。我怎样才能使NavigationLink 工作?

有什么帮助吗?谢谢!

【问题讨论】:

由于“建议的编辑队列已满”,我将在此处添加我的建议作为评论...您最好问一下,如何在同一个列表单元格中使用多个 NavigationLink。跨度> @Yodagama 谢谢,我正在尝试使用两个Button 控制isActive 和一个NavigationLink,不确定它是否有帮助,只是在这个问题上花费了两个时间。如果我不能让它发挥作用,我会选择你的方法,。 是的,您可以采用这种方法,以某种方式您可以在列表单元格中一次使用一个处于活动状态的 NavigationLink。 这是否回答了您的问题***.com/a/63497954/12299030 或***.com/a/63197406/12299030? @Yodagama 是的,但是你可以控制目的地`destination: isDestination1Clicked? AnyView(Destination1()) : AnyView(Destination2())` 【参考方案1】:

在 List 中定义了一些限制,只能是 List 本身。

这样我们不能在一个列表单元格中使用多个 NavigationLink(如果我们使用多个 NavigationLink,我们将无法获得预期的行为)

而且空视图也不会获得触摸事件。

这是您的代码的修复。

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()
    

【讨论】:

谢谢,这行得通。我也用一个 navigationLink 厌倦了两个 Button,它终于可以工作了。【参考方案2】:

尝试将“onTapGesture”附加到“NavigationView”。

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

【讨论】:

嗨,你试过了吗?我只是累了还是一样。 是的,试过了,我在使用 xcode 12.2 beta 的 macos 11 和 ios 14.2 上运行良好。因为你设置它的方式,你需要点击几次。 我正在使用 macOS 10.15 和 Xcode 12。仍然没有运气。 更正。它现在对我来说大部分时间都有效。在 macOS 11 上,当我点击说 D1 时,它有时没有响应。我还收到“SwiftUI 在推送导航链接时遇到问题。请提交错误。”在控制台中。 SwiftUI 中的 NavigationLink 没有问题。你可能做错了。

以上是关于SwiftUI onTapGesture 块 NavigationLink 动作的主要内容,如果未能解决你的问题,请参考以下文章

SwiftUI .onTapGesture 从未调用过

onTapgesture 禁用 View SwiftUI 的按钮

SwiftUI 使用 onTapGesture 和 onLongPressGesture 处理按钮/视图以及释放操作

SwiftUI:带有onTapGesture的列表单元格内的菜单触发手势

SwiftUI onTapGesture 仅调用一次

LazyVGrid onTapGesture 导航到下一个屏幕 swiftUI