弹出到“根视图”时缺少目的地

时间:2020-07-27 13:13:20

标签: swiftui swiftui-navigationlink

我已经提到了这个堆栈溢出线程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作为环境对象传递),并且在按下按钮时,将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线程中有一个帖子要使用@State中的RootView -> FirstView变量,而EnvironmentObject中有一个变量{{ 1}}。然后在moveToDashbord上添加一个RootView修饰符以监听.onReceive发布者,然后触发moveToDashboard变量。但这又导致了相同的调试控制台消息。

简而言之,所有解决方案都会导致缺少目标控制台消息。这是因为导航太深了吗?

这是一个仅iPad 项目,并且navigationView样式设置为StackedNavigationStyle。

系统详细信息:

Xcode 11.6

iOS / PadOS Target 13.0(因此,请不要使用SwiftUI 2.0)

代码示例:

这是SceneDelegate,它将AppSettings设置为系统范围内的EnvironmentObject。

@State

这是到RootView的NavigationLink的示例

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-> FirstView中的navigationLink的示例:

NavigationLink(destination: RootView().navigationBarBackButtonHidden(true), isActive: self.$loginViewModel.loginSuccess) {
    EmptyView()
}

注意。为了澄清起见,我不得不更改视图的实际名称。

1 个答案:

答案 0 :(得分:0)

我发现了问题,在其中一个视图上有一个UIViewControllerRepresentable包装的UIAlertController。它被构造为具有内容准备的视图修饰符。

这基本上覆盖了原始视图,最终破坏了导航堆栈。

解决方案是包装由View呈现的UIViewController,并且该ViewController驻留在UIAlertController中。

使用并修改了SwiftUI - UIAlertController

的UIAlertController解决方案