【问题标题】:Is it possible to have multiple NavigationLinks per row in a List SwiftUI?List SwiftUI 中的每行是否可以有多个 NavigationLink?
【发布时间】:2019-09-09 16:03:04
【问题描述】:

我不能在 List 的同一行中使用多个 NavigationLink。

看起来导航堆栈完全搞砸了,因为您点击一次,它会进入多个视图,然后不规律地返回......

在 TestList 中,我尝试在 Sections 中添加单独的 NavigationLinks,并尝试将 NavigationLinks 移动到视图层次结构中的两个不同位置...

我尝试为列表的每一行添加两个 NavigationView,但是 那么当我需要它时,navigationTitleBar 就不会消失..


struct ContentView: View {
    var body: some View {

        NavigationView {
            TestList()
        }


    }
}


struct TestList: View {
    var body: some View {

        List  {
            ListCellView()

        }

    }
}


struct ListCellView: View {

    var body: some View {
        VStack {
            Spacer()

            NavigationLink(destination: TestDestination1())  {
                Text("Test Destination 1")
                    .frame(width: 140, height: 50)
                    .background(RoundedRectangle(cornerRadius: 7.0).strokeBorder(Color.green, lineWidth: 3.0))
            }

            Spacer()

            NavigationLink(destination: TestDestination2())  {
                Text("Test Destination 2")
                    .frame(width:140, height: 50)
                    .background(RoundedRectangle(cornerRadius: 7.0).strokeBorder(Color.purple, lineWidth: 3.0))
                Spacer()
            }
        }
    }
}


struct TestDestination1: View {
    var body: some View {
        Text("Test Destination 1")
    }
}

struct TestDestination2: View {
    var body: some View {
        Text("Test Destination 2")
    }
}


我希望当您点击 NavigationLink 时,它会导航到目标视图。

当两个 NavigationLinks 在 List 的同一行中并且您点击它时,会发生什么情况: 1. 转到其中一个视图 2.点击“返回”后,它会带你回到视图,然后带你到另一个目标视图。

https://youtu.be/NCTnqjzJ4VE

【问题讨论】:

  • 这似乎是 SwiftUI 中的一种模式,如果你坚持默认设置,事情会很好,但如果你做了一些意想不到的事情,事情会很快变得非常混乱。如果有可能将两个NavigationLinks 分成两个列表项,我会这样做。
  • 导航栈没有问题。你想达到什么样的行为?您不会期望在 UITableView 中点击一个单元格来同时导航到两个不同的视图,对吗?
  • @LuLuGaGa 这是一个很好的观点......我试图在列表行中有多个视图。我会尝试像@Benjamin\ Kindle 建议的那样拆分它。
  • @BenjaminKi​​ndle 是的,我认为这是可能的。这可能是解决方案。

标签: swiftui


【解决方案1】:

正如其他人提到的,为什么 1 个单元格中有 2 个 NavigationLinks。问题在于 Cell 通常有多个按钮和手势。我猜预计每个单元格最多 1 个 Button/NavigationLink。正如您所注意到的,在您的视频中,您点击了 NavigationLink,但您的完整单元格得到了手势(突出显示),这反过来会影响其他按钮/导航链接。

无论如何,你可以让它工作,1 个单元格中的 2 个 NavigationLinks,只需 hack。下面我创建了 SGNavigationLink,我将它用于我自己的应用程序来解决您的问题。它只是替换 NavigationLink 并基于 TapGesture,因此您将失去高亮。

注意:我稍微修改了您的 ListCellView,因为我的 SGNavigationLink 中的 Spacer 正在造成内部崩溃。

struct ListCellView: View {

    var body: some View {
        VStack {

            HStack{
                SGNavigationLink(destination: TestDestination1())  {
                    Text("Test Destination 1")
                        .frame(width: 140, height: 50)
                        .background(RoundedRectangle(cornerRadius: 7.0).strokeBorder(Color.green, lineWidth: 3.0))
                }

                Spacer()
            }

            HStack{
            SGNavigationLink(destination: TestDestination2())  {
                Text("Test Destination 2")
                    .frame(width:140, height: 50)
                    .background(RoundedRectangle(cornerRadius: 7.0).strokeBorder(Color.purple, lineWidth: 3.0))

            }
            Spacer()
            }
        }
    }
}



struct SGNavigationLink<Content, Destination>: View where Destination: View, Content: View {
    let destination:Destination?
    let content: () -> Content


    @State private var isLinkActive:Bool = false

    init(destination: Destination, title: String = "", @ViewBuilder content: @escaping () -> Content) {
        self.content = content
        self.destination = destination
    }

    var body: some View {
        return ZStack (alignment: .leading){
            if self.isLinkActive{
                NavigationLink(destination: destination, isActive: $isLinkActive){Color.clear}.frame(height:0)
            }
            content()
        }
        .onTapGesture {
            self.pushHiddenNavLink()
        }
    }

    func pushHiddenNavLink(){
        self.isLinkActive = true
    }
}

【讨论】:

    【解决方案2】:

    我不确定您为什么需要多个 导航链接(重复代码)。您可以使用一个数据源来保存列表所需的属性 [标题、颜色、id 等],并根据 id 调用所需的视图。重复使用相同的代码。这是一个例子。

    struct TestList: View {
        var body: some View {
            List { // <- Use Data source 
                ForEach(0..<2) { index in
                     ListCellView(index: index)
                }
            }
        }
    }
    
    struct ListCellView: View {
        var index: Int
        var body: some View {
             return   NavigationLink(destination: ViewFactory.create(index))  {
                    Text("Test Destination 1")
                        .frame(width: 140, height: 50)
                        .background(RoundedRectangle(cornerRadius: 7.0).strokeBorder(Color.green, lineWidth: 3.0))
                }
        }
    }
    
    
    class ViewFactory {
       static func create(_ index: Int) -> AnyView {
            switch index {
            case 0:
                return AnyView(TestDestination1())
            case 1:
                return AnyView(TestDestination2())
            default:
               return AnyView(EmptyView())
            }
        }
    }
    
    struct TestDestination1: View {
        var body: some View {
            Text("Test Destination 1")
        }
    }
    
    struct TestDestination2: View {
        var body: some View {
            Text("Test Destination 2")
        }
    }
    

    【讨论】:

    • 太棒了,你节省了我很多时间 :)
    猜你喜欢
    • 1970-01-01
    • 2020-11-12
    • 1970-01-01
    • 2023-04-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-07
    • 1970-01-01
    相关资源
    最近更新 更多