swiftui - SwiftUI 导航控制器卡顿,每个列表行有两个 Navigationlinks
问题描述
我正在尝试在重复列表中创建两个 NavigationLink。每个都有一个单独的目的地。在我将对根视图的调用嵌入到 List/ForEach 循环之前,代码一切正常。此时导航变得非常奇怪。
尝试单击任一链接,然后单击顶部的后退指示器。它将转到一个 NavigationLink,然后转到另一个。有时以不同的顺序,有时它会从一个链接自动返回,有时它不会打开第二个详细视图,直到您从第一个详细视图返回。它在 Preview 中以及在您构建和运行应用程序时都执行此操作。
我已将代码提炼为以下最基本的代码。如果您按照 ContentView 中的说明注释 2 行,您将看到正确的行为。
我正在运行 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")
}
}
}
解决方案
在您的情况下,两个导航链接都会在用户点击一行时立即激活,为避免这种情况,下面是可能的方法
使用 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()
}
}
}
推荐阅读
- reactjs - Error-Hooks 只能在函数组件的主体内部调用
- excel - 根据用户列表框选择填充 14 个不同的文本框
- python - pytorch,在 LSTM 中使用 nn.DataParallel
- ruby-on-rails - 升级到 Rails 6 后未发现关联错误
- python-3.x - 是否可以用字典列表映射列表
- java - 如何将过渡动画(淡入、淡出)从 jframe 更新到另一个 jframe?
- linux - 致命错误:kdecoration.h:没有这样的文件或目录
- asp.net-core-mvc - 想要一个通用的 EnterpriseLibrary for .NET Core MVC(通用数据库文件)
- go - 切片索引奇怪的边缘情况
- javascript - 基于另一个对象的值访问对象的属性