【问题标题】:SwitUI - Two navigationLink in a listSwiftUI - 列表中的两个导航链接
【发布时间】:2020-08-20 01:53:54
【问题描述】:

我的列表单元格中有两个 NavigationLink

我想点击一次去destination1,点击两次去destination2。 所以我添加了两个点击手势来控制导航。

但是当我点击时,有两个问题:

  • 1 不会调用点击手势块。
  • 2 这两个导航链接即使在 TextView 后面也会自动激活。 真正的效果是:点击单元格->去Destination1->返回首页->去Destination2->返回首页

这是我的代码:

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

我已经尝试删除 List 元素,然后一切都按我的预期进行。 似乎是 List 元素让一切变得奇怪。

我找到了这个问题:SwiftUI - Two buttons in a List,但情况和我不一样。

期待您的回复,非常感谢...

【问题讨论】:

  • 我认为您的架构不正确。尝试从List 中删除ZStackNavigationLink 并替换为Button,然后将.onTapGesture 修饰符应用于Button,将导航链接嵌入到每个perform 代码中。跨度>

标签: ios list swiftui swiftui-navigationlink vstack


【解决方案1】:

尝试以下方法 - 想法是在可见内容的背景中隐藏链接,并使它们对 UI 无效,但以编程方式激活。

使用 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
        }
    }
}

【讨论】:

  • 这个解决方案完全符合我的需求。最后,我发现当一个列表单元格包含多个导航链接时,您点击该单元格一次,所有导航链接都会被激活。一个关键点是设置它们disable(true),并通过其他单独的逻辑激活每个导航链接。
  • @Asperi 我相信你是个天才
【解决方案2】:

导航链接有一个初始化器,它接受绑定selection,只要将selection 设置为NavigationLink tag 的值,导航链接就会触发。 作为提示,如果应用程序无法区分和识别您的点击,即使两次点击,仍然会触发一键操作,那么您可以使用同时手势(.simultaneousGesture())修饰符而不是正常手势(.gesture()) 修饰符。

struct someViewName: View {
    
    @State var navigationLinkTriggererForTheFirstOne: Bool? = nil
    @State var navigationLinkTriggererForTheSecondOne: Bool? = nil
    
    var body: some View {
        VStack {
            NavigationLink(destination: SomeDestinationView(),
                           tag: true,
                           selection: $navigationLinkTriggererForTheFirstOne) {
                EmptyView()
            }
            
            NavigationLink(destination: AnotherDestinationView(),
                           tag: true,
                           selection: $navigationLinkTriggererForTheSecondOne) {
                EmptyView()
            }
            
            NavigationView {
                    Button("tap once to trigger the first navigation link.\ntap twice to trigger the second navigation link.") {
                        // tap once
                        self.navigationLinkTriggererForTheFirstOne = true
                    }
                    .simultaneousGesture(
                        TapGesture(count: 2)
                            .onEnded { _ in
                                self.navigationLinkTriggererForTheSecondOne = true
                            }
                    )
            }
        }
    }
}

【讨论】:

  • 当我在没有列表元素的情况下使用它时,这个元素效果很好。但是当我将元素放入列表中时,点击它,它也没有像我们预期的那样运行。
猜你喜欢
  • 2020-05-28
  • 2022-01-16
  • 1970-01-01
  • 1970-01-01
  • 2022-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多