SwiftUI - 使用“pushViewController”时出现致命错误

Posted

技术标签:

【中文标题】SwiftUI - 使用“pushViewController”时出现致命错误【英文标题】:SwiftUI - Fatal Error When Using 'pushViewController' 【发布时间】:2019-08-13 02:01:17 【问题描述】:

因为 SwiftUI 有如此令人窒息的导航系统,所以我尝试在我的 SwiftUI 视图中使用 pushViewController

但是,当我运行代码并按下按钮时,我收到以下错误 -

Fatal error: Unexpectedly found nil while unwrapping an Optional value:
file /Users/.../Conjugate/Conjugate/Pages/Practice/PracticeView.swift, line 93

这是我的代码 -

PracticeView.swift

...
Button(action:     
             /* Line 93 */ UIApplication.shared.windows[0].rootViewController?.navigationController!.pushViewController(UIHostingController(rootView: ResultView()), animated: true)
)  ... 
...

SceneDelegate.swift

...
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) 
    if let windowScene = scene as? UIWindowScene 
        let window = UIWindow(windowScene: windowScene)

        let nonEmbeddedViewController = UIHostingController(rootView: PracticeView(verb: verbData.shuffled(), numberOfQuestions: CGFloat(verbData.count)))
        let navigationController = UINavigationController(rootViewController: nonEmbeddedViewController)

        window.rootViewController = navigationController

        self.window = window
        window.makeKeyAndVisible()
    

...

有人知道如何解决这个问题吗?我怀疑navigationController 在展开时的值为 nil,但我不知道解决方案。谢谢!

编辑 - 澄清

我正在尝试制作一款针对某个主题对您进行测验的教育应用。 “实践视图”是用户回答问题的地方,每次他们按下右下角的按钮(我在问题中提到的那个)时都会被替换。但是,当所有问题都已回答后,按钮需要打开另一个视图(“结果视图”),而不是仅仅切换当前视图中的文本。此外,导航栏必须在练习视图和结果视图中都隐藏,而模态表则不行。如果您需要参考,我猜 Duolingo 或 this slideshow 可能会有用。

【问题讨论】:

对我来说,这听起来像是你在“对抗”这个过程。在 SwiftUI 中导航有什么“令人窒息”的? (我不是在和你争论,只是想知道是否有人可以更好地帮助你。)由于 SwiftUI 是一个与 UIKit 完全不同的堆栈,我很确定你已经知道你正在做的事情,而它可能今天可以工作,可能会在下一个测试版中中断 - 或者更糟糕的是,一年后你在生产应用程序中实现它。 (如果我能说出 4 年前我为自动布局“战斗”了多少,你就会知道我理解你的处境。) 我刚刚用更多的背景信息编辑了我的答案。希望这能澄清我的问题,并感谢您的关注!如果可行,我会完全接受另一种方法。是的,我确实对未来解决方法的功能有些担忧。 【参考方案1】:

代码降价可能会帮助您。忽略 SwiftUI 导航视图,放开需要显示 (a) 练习视图(带有一系列问题)或 (b) 结果的模型。如果您使用以下方式设置模型:

@Published var currentQuestion:Question
@Published var showResults:Bool

(这是非常很多伪代码!)

您实际上可以拥有一个(简单的)内容视图(同样是伪代码),即:

struct ContentView: View 
    @EnvironmentObject var model: Model

    var body: some View 
        if model.showResults 
            ShowResults()
         else 
            ShowCurrentQuestion()
        
    

ShowResultsShowCurrentQuestionViews。你可以在两者之间做各种动画(默认是淡入淡出),完全不需要“导航”。只要您的模型驱动 ContentView,它就可以工作。

是的,我不是针对NavigationView 说的——虽然我在UINavigationController 方面是“老派”,但我正在开发的 SwiftUI 应用程序不需要任何类似于 push/pop 或 segues 的东西.但是...我正在使用我刚刚描述的内容。)

【讨论】:

对不起,但我真的想不出一个正确的方法来执行这个。我对我的更新作品提出了另一个问题,如果您有兴趣,可以在这里 (***.com/questions/57488322/…) 找到。

以上是关于SwiftUI - 使用“pushViewController”时出现致命错误的主要内容,如果未能解决你的问题,请参考以下文章

使用xib ios7从presentviewcontroller准备推送segue

在SwiftUI项目中使用UIKit(SwiftUI和UIKit混合开发)

如何在 SwiftUI 中使用 Realm

使用 SwiftUI 实现应用内购买 [关闭]

SwiftUI 使用SwiftUI实现跑马灯效果 Marquee

SwiftUI 使用SwiftUI实现跑马灯效果 Marquee