列表SwiftUI中每行是否可以有多个NavigationLink?

时间:2019-09-09 16:03:04

标签: swiftui

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

由于您轻按了一下,它会转到多个视图,然后不规律地返回...,看来导航堆栈完全被弄乱了。

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

我尝试为列表的每一行添加两个NavigationViews,但是 那么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在一个列表的同一行中并单击它时,会发生以下情况:   1.进入其中一种观点   2.点击“返回”后,将带您回到视图,然后带您到另一个目标视图。

https://youtu.be/NCTnqjzJ4VE

2 个答案:

答案 0 :(得分:1)

正如其他人提到的,为什么要在1个单元格中使用2个NavigationLinks。问题是该单元通常具有多个按钮和手势。我猜应该每个单元格最多1个Button / NavigationLink。如您所见,在视频上,您点击了NavigationLink,但是整个单元格获得了手势(突出显示),这反过来又影响了其他Buttons / NavigationLinks。

无论如何,您可以使用一个hack,在一个单元格中使用两个NavigationLinks。下面,我创建了SGNavigationLink,我将其用于自己的应用程序来解决您的问题。它只是替换了NavigationLink并基于TapGesture,因此您将失去亮点。

注意:由于SGNavigationLink中的Spacer正在造成内部崩溃,因此我对ListCellView进行了一些修改。

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

答案 1 :(得分:0)

我不确定为什么需要多个 Navigationlinks (重复代码)。您可以使用将保留列表的必要属性的数据源[标题,颜色,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")
    }
}