SwiftUI导航控制器每个列表行有两个导航链接

SwiftUI导航控制器每个列表行有两个导航链接,swiftui,swiftui-list,swiftui-navigationlink,ios-navigationview,swiftui-foreach,Swiftui,Swiftui List,Swiftui Navigationlink,Ios Navigationview,Swiftui Foreach,我正在尝试在重复列表中创建两个导航链接。每个都有一个单独的目的地。在我将对根视图的调用嵌入到List/ForEach循环中之前,代码都可以正常工作。此时导航变得非常奇怪 尝试单击任一链接,然后单击顶部的后退指示器。它将转到一个NavigationLink,然后转到另一个。有时以不同的顺序,有时它将从其中一个链接自动返回,有时它将在您从第一个局部视图返回之前不会打开第二个局部视图。它在预览中以及在构建和运行应用程序时都会执行此操作 我已经将代码提炼到下面最基本的部分。如果按照ContentView

我正在尝试在重复列表中创建两个导航链接。每个都有一个单独的目的地。在我将对根视图的调用嵌入到List/ForEach循环中之前,代码都可以正常工作。此时导航变得非常奇怪

尝试单击任一链接,然后单击顶部的后退指示器。它将转到一个NavigationLink,然后转到另一个。有时以不同的顺序,有时它将从其中一个链接自动返回,有时它将在您从第一个局部视图返回之前不会打开第二个局部视图。它在预览中以及在构建和运行应用程序时都会执行此操作

我已经将代码提炼到下面最基本的部分。如果按照ContentView中的指示对这两行进行注释,您将看到正确的行为

我正在运行Catalina 10.15.5,xCode 11.6,应用程序目标是IOS 13.6

如何修改代码,使其与List/ForEach循环一起工作

import SwiftUI

struct DetailView1: View {
    var body: some View {
        HStack {
            Text("Here is Detail View 1." )}
            .foregroundColor(.green)
    }
}

struct DetailView2: View {
    var body: some View {
        HStack {
            Text( "Here is Detail View 2.") }
            .foregroundColor(.red)
    }
}

struct RootView: View {
    var body: some View {
        HStack {
            VStack {
                NavigationLink(destination: DetailView1())
                { VStack { Image(systemName: "ant.circle").resizable()
                    .frame(width:75, height:75)
                    .scaledToFit()
                }.buttonStyle(PlainButtonStyle())
                    Text("Tap for Detail 1.")
                        .foregroundColor(.green)
                }
            }
            NavigationLink(destination: DetailView2())
            { Text("Tap for Detail 2.")
                .foregroundColor(.red)
            }
        }
    }
}

struct ContentView: View {
    var body: some View {
        NavigationView {
            // Comment the following line for correct behavior
            List { ForEach(0..<3) {_ in
                RootView()
                // Comment the following line for correct behavior
                }  }
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        NavigationView {
            ContentView()
                .navigationBarTitle("Strange Behavior")
        }
    }
}
导入快捷界面
结构详细视图1:视图{
var body:一些观点{
HStack{
文本(“这是详细视图1”)}
.foregroundColor(.绿色)
}
}
结构详细视图2:视图{
var body:一些观点{
HStack{
文本(“这是详细视图2”)}
.foregroundColor(.red)
}
}
结构RootView:View{
var body:一些观点{
HStack{
VStack{
NavigationLink(目标:DetailView1())
{VStack{Image(系统名:“ant.circle”).resizeable()
.框架(宽度:75,高度:75)
.scaledofit()
}.buttonStyle(PlainButtonStyle())
文本(“点击查看详细信息1”)
.foregroundColor(.绿色)
}
}
NavigationLink(目标:DetailView2())
{文本(“点击查看详细信息2”)
.foregroundColor(.red)
}
}
}
}
结构ContentView:View{
var body:一些观点{
导航视图{
//注释以下行以了解正确的行为

列表{ForEach(0..在您的情况下,两个导航链接都会立即激活,用户点击一行,以避免这种情况,下面是可能的方法

使用Xcode 12/iOS 14进行测试

其思想是有一个链接,该链接通过编程激活,并根据单击的按钮动态选择目的地

struct RootView: View {
    @State private var isFirst = false
    @State private var isActive = false
    var body: some View {
        HStack {
            VStack {
                Button(action: {
                    self.isFirst = true
                    self.isActive = true
                })
                { VStack { Image(systemName: "ant.circle").resizable()
                    .frame(width:75, height:75)
                    .scaledToFit()
                }
                    Text("Tap for Detail 1.")
                        .foregroundColor(.green)
                }
            }
            Button(action: {
                self.isFirst = false
                self.isActive = true
            })
            { Text("Tap for Detail 2.")
                .foregroundColor(.red)
            }
            .background(
                NavigationLink(destination: self.destination(), isActive: $isActive) { EmptyView() }
            )
        }
        .buttonStyle(PlainButtonStyle())
    }

    @ViewBuilder
    private func destination() -> some View {
        if isFirst {
            DetailView1()
        } else {
            DetailView2()
        }
    }
}

这也适用于我的版本,我会接受答案,但我想问一个问题。有没有办法设置NavigationLinks的区域,使其适用于所附加的对象,而不是整行?目前,native SwiftUI列表不提供这种可能性。完全可以删除链接,因此禁用default突出显示,并制定完全自定义的解决方案,但这是一个有点工作和不讨论的话题。