0

Because SwiftUI has such a stifling navigational system, I'm attempting to use pushViewController within my SwiftUI views.

However, when I run the code and press the button, I get the following error -

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

Here is my code -

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()
    }
}
...

Does anybody know how to fix this? I suspect that the navigationController has a value of nil when unwrapped, but I don't know the solution. Thank you!

EDIT - Clarification

I'm trying to make an educational app that quizzes you on a certain topic. The "practice view" is where the user answers questions, which get replaced every time they press the button in the bottom right corner (the one I mentioned in my question). However, when all the questions have been answered, the button needs to open another view (the "result view") instead of just switching the text in the current view. In addition, the navigation bar must be hidden in both the practice view and the result view, and modal sheets won't do. If you need a reference, I guess Duolingo or this slideshow could be useful.

2
  • 1
    To me it sounds like you're "fighting" the process. What's "stifling" about navigating in SwiftUI? (I'm not arguing with you, just wondering if with more details someone could help you better.) Since SwiftUI is a completely different stack than UIKit, I'm pretty sure you already know you're doing things that, while it may be working today, could break in the next beta - or worse, a year from now when you implemented this in a production app. (If I could name you how much I "fought" auto-layout 4 years ago, you'd know that I understand where you're at.) Commented Aug 13, 2019 at 2:19
  • I just edited my answer with a bit more background information. Hope this clarifies my issue, and thank you for your interest! I would completely accept a different method if it works. And yes, I do have some concerns about the functionality of my workaround in the future. Commented Aug 13, 2019 at 3:00

1 Answer 1

1

Code markdown may help you for this. Ignoring the SwiftUI navigation view, let go with a model that need to show either (a) a practice view (with an array of questions) or (b) the results. If you set up your model with:

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

(This is very much pseudo-code!)

You can actually have a (simple) content view (again, pseudo-code) that is:

struct ContentView: View {
    @EnvironmentObject var model: Model

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

ShowResults and ShowCurrentQuestion are Views. You can do all kinds of animation (the default is to fade in/out) between the two, and there's absolutely no need for "navigation". As long as your model drives ContentView, it works.

And yes, I'm not addressing NavigationView - while I'm 'old school" with regards to UINavigationController, the SwiftUI app I'm working on doesn't need anything similar to push/pop or segues. BUT... I am using what I've just described.)

Sign up to request clarification or add additional context in comments.

1 Comment

Sorry, but I really couldn't figure out a proper way to execute this. I've asked another question with my updated work, which you can find here (stackoverflow.com/questions/57488322/…) if you're interested.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.