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

SwiftUI Navigation Controller stuttering with two Navigationlinks per List row

我正在尝试在重复列表中创建两个 NavigationLink。每个都有一个单独的目的地。在我将对根视图的调用嵌入 List/ForEach 循环之前,代码一切正常。这时候导航就变得很奇怪了

尝试点击任一 link,然后点击顶部的后退指示器。它将转到一个 NavigationLink,然后转到另一个。有时顺序不同,有时它会从 link 中的一个自动 return,有时它不会打开第二个详细视图,直到您从第一个详细信息 return看法。它在预览版中以及构建和 运行 应用程序时都会执行此操作。

我已经将代码提炼为最基本的代码。如果您按照 ContentView 中的指示注释 2 行,您将看到正确的行为。

我是运行宁卡塔琳娜10.15.5,xCode11.6,应用目标IOS13.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")
        }
    }
}

在您的情况下,两个导航 link 都会在用户点击一行后立即激活,为了避免这种情况,可以采用以下方法

测试 Xcode 12 / iOS 14

想法是有一个 link 以编程方式激活并根据单击哪个按钮动态选择目标

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