弹出到根视图时缺少目标
Posted
技术标签:
【中文标题】弹出到根视图时缺少目标【英文标题】:Missing Destination when pop to Root View 【发布时间】:2020-07-27 13:13:20 【问题描述】:我已经提到了这个 Stack Overflow 线程 SwiftUI How to Pop to root view。
但是它不适用于我的情况,当然没有答案完全适合每个人的用例,所以总是需要稍微修改答案,但当然要保持解决方案的总体轮廓。
我看过这个帖子How to popup multiple view off navigation stack,但我不确定重置场景是最好的选择吗?必须有一个“正常”的方式?
我采用的解决方案是使用 ObservableObject 并将其设置为根视图的 EnvironmentObject。
导航堆栈增加了 4 个视图:
RootView().environmentObject(AppSettings.shared)
FirstView()
SecondView()
ThirdView()
FourthView()
FirstView 的 NavigationLink isActive
状态在 AppSettings.shared
中定义,所有其他状态都在后续视图中找到,而不是在 AppSettings 中。
例如:
FirstView -> SecondView
SecondView isActive
状态定义在 FirstView
的 ViewModel 中,以此类推。
我想要实现的是从FourthView 弹出到RootView。所以在 FourthView 上有一个 AppSettings 类型的 environmentObject 变量(从 RootView 作为 EnvironmentObject 传递),按下按钮时,将 RootView -> FirstView isActive 状态切换为 false。
它会切换,但没有导航。 但是,在调试控制台中,这是错误
Trying to pop to a missing destination at /Library/Caches/com.apple.xbs/Sources/Monoceros/Monoceros-42.24.100/Shared/NavigationBridge_PhoneTV.swift:205
根据我的理解,将该状态切换为 false 应该会触发返回导航,但在 Stack Overflow 线程中有一个帖子使用来自 RootView -> FirstView
的 @State
变量,并且在 EnvironmentObject 中有一个变量 moveToDashbord
。然后在RootView
上添加.onReceive
修饰符以监听moveToDashboard
发布者,然后触发@State
变量。但这同样会导致相同的调试控制台消息。
简而言之,所有解决方案都会导致缺少目标控制台消息。是不是因为导航太深了?
这是一个仅限iPad项目,navigationView 样式设置为 StackedNavigationStyle。
系统详情:
Xcode 11.6
ios/PadOS Target 13.0(所以不使用 SwiftUI 2.0,如果有的话)
代码示例:
这是将 AppSettings 设置为系统范围的 EnvironmentObject 的 SceneDelegate。
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions)
let contentView = LoginView().environmentObject(AppSettings.shared)
if let windowScene = scene as? UIWindowScene
let window = UIWindow(windowScene: windowScene)
window.rootViewController = UIHostingController(rootView: contentView)
self.window = window
window.makeKeyAndVisible()
这是到 RootView 的导航链接示例
NavigationLink(destination: RootView().navigationBarBackButtonHidden(true), isActive: self.$loginViewModel.loginSuccess)
EmptyView()
这是来自 RootView -> FirstView 的 navigationLink 示例:
NavigationLink(destination: FirstView().environmentObject(FirstViewModel()), isActive: self.$appSettings.firstView)
EmptyView()
.isDetailLink(false)
注意。为了清楚起见,我不得不更改视图的实际名称。
【问题讨论】:
测试所需的示例。 How to create a Minimal, Reproducible Example 让我创建一个 它在一个干净的项目中工作.. 我的实现肯定有问题,或者视图中的某些 UI 元素导致中断。 【参考方案1】:我发现了问题,在其中一个视图上有一个 UIViewControllerRepresentable 包装的 UIAlertController。它被构造为一个视图修饰符,提供内容。
这基本上覆盖了最终破坏导航堆栈的原始视图。
解决方案是包装一个由 View 呈现的 UIViewController,并且在 ViewController 中驻留 UIAlertController。
这个 UIAlertController 的解决方案被使用和改编SwiftUI - UIAlertController
【讨论】:
以上是关于弹出到根视图时缺少目标的主要内容,如果未能解决你的问题,请参考以下文章