最小的可重现示例(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在navigationBarItems嵌套于SwiftUI视图(其根视图为)的修改器内部NavigationView。崩溃报告指出,我试图弹出来,当我浏览着那个不存在的视图控制器Child,然后返回Parent。
NavigationLink
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错误还是预期行为?
编辑:我已经在Apple的反馈助理中用ID打开了一个问题,FB7423964以防Apple有人担心:)。
FB7423964
编辑:我在反馈助手中打开票证表明有10多个类似的已报告问题。他们已使用更新了分辨率Resolution: Potential fix identified - For a future OS update。手指交叉,修复很快就到了。
Resolution: Potential fix identified - For a future OS update
编辑:这已在iOS 13.3中修复!
这对我来说是很痛苦的一点!我把它留了下来,直到我的大多数应用程序完成为止,并且我有足够的空间来处理崩溃问题。
我认为我们都可以同意SwifUI有一些很棒的东西,但是调试可能很困难。
我认为这是一个错误。这是我的基本原理:
如果以大约半秒的异步延迟包装presentationMode dismiss调用,则应该发现程序不再崩溃。
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { self.presentationMode.wrappedValue.dismiss()
}
这向我表明,该错误是SwiftUI如何与所有其他UIKit代码进行接口以管理各种视图的一个无法预料的行为。根据您的实际代码,您可能会发现,如果视图中的复杂性较小,则崩溃实际上不会发生。例如,如果您从一个视图中退出到一个具有列表的视图,并且该列表为空,则将在没有异步延迟的情况下崩溃。另一方面,如果在该列表视图中甚至只有一个条目,则强制循环迭代以生成父视图,您将看到崩溃不会发生。
I’m not so sure how robust my solution of wrapping the dismiss call in a delay is. I have to test it much more. If you have ideas on this, please let me know! I’d be very happy to learn from you!