最小的可复制示例(Xcode 11.2 beta,在Xcode 11.1中有效):
struct Parent: View {
var body: some View {
NavigationView {
Text("Hello World")
.navigationBarItems(
trailing: NavigationLink(destination: Child(), label: { Text("Next") })
)
}
}
}
struct Child: View {
@Environment(\.presentationMode) var presentation
var body: some View {
Text("Hello, World!")
.navigationBarItems(
leading: Button(
action: {
self.presentation.wrappedValue.dismiss()
},
label: { Text("Back") }
)
)
}
}
struct ContentView: View {
var body: some View {
Parent()
}
}
[问题似乎在于将我的NavigationLink
放在嵌套在SwiftUI视图中的navigationBarItems
修饰符内,该修饰符的根视图是NavigationView
。崩溃报告表明,当我向前导航至Child
然后返回至Parent
时,我试图弹出一个不存在的视图控制器。
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Tried to pop to a view controller that doesn't exist.'
*** First throw call stack:
[如果我将NavigationLink
放置在如下所示的视图主体中,则可以正常工作。
struct Parent: View {
var body: some View {
NavigationView {
NavigationLink(destination: Child(), label: { Text("Next") })
}
}
}
这是SwiftUI错误还是预期的行为?
[我想我们都同意SwifUI有一些很棒的东西,但是调试可能很困难。
我认为这是一个错误。这是我的基本原理:
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
self.presentationMode.wrappedValue.dismiss()
}
我不确定在延迟中包装dismiss调用的解决方案有多健壮。我必须测试更多。如果您对此有任何想法,请告诉我!我很高兴向您学习!
通过设置前导项目,您实际上杀死了导航过渡的默认行为。 (尝试从前端滑动以查看是否有效)。
因此无需在此处设置按钮。只需保留它,您就可以拥有一个免费的后退按钮。
并且根据
HIG别忘了,后退按钮标题应该显示它的去向,not它是什么!因此,请尝试为首页设置标题,以向其显示弹出的所有后退按钮。
struct Parent: View {
var body: some View {
NavigationView {
Text("Hello World")
.navigationBarItems(
trailing: NavigationLink(destination: Child(), label: { Text("Next") })
)
.navigationBarTitle("First Page",displayMode: .inline)
}
}
}
struct Child: View {
@Environment(\.presentationMode) var presentation
var body: some View {
Text("Hello, World!")
}
}
struct ContentView: View {
var body: some View {
Parent()
}
}