NavigationLink is not clickable after returning to the view from it's child view

601 views Asked by At

My app has a multilevel layout AView -> BView -> CView -> DView.

I change

window.rootViewController

to BView in order to "pop" 2 top views but for some reason when i come back to BView it's NavigationLink is not clickable.

Any ideas on how to fix this? It seems like BView doesn't know that it became visible..

AView.swift:

import SwiftUI

struct AView: View {
    
    init() {
        print("AView init")
    }
    

    var body: some View {
        
        NavigationView {
            VStack {
                NavigationLink(destination: BView()) {
                    Text("This is View A, now go to View B.")
                }
            }
        }
    }
}

struct BView: View {
    init() {
        print("BView init")
    }
    

    var body: some View {
        NavigationLink(destination: CView()) {
                Text("This is View B, now go to View C.")
        }
    }
}

struct CView: View {
    
    init() {
        print("CView init")
    }
    
    var body: some View {
        NavigationLink(destination: DView()) {
                Text("This is View C, now go to View D.")
        }
    }
}

struct DView: View {
    init() {
        print("DView init")
    }
    
    var body: some View {

        Button(action: {
            print("button pressed")
            (UIApplication.shared.connectedScenes.first?.delegate as? SceneDelegate)?.toBView()

        },
               label: {
            Text("Back!")
        })

    }
}

SceneDelegate.swift:

import UIKit
import SwiftUI

class SceneDelegate: UIResponder, UIWindowSceneDelegate {

    var window: UIWindow?

    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
        // Create the SwiftUI view that provides the window contents.
        let aView =     AView()
        
        // Use a UIHostingController as window root view controller.
        if let windowScene = scene as? UIWindowScene {
            let window = UIWindow(windowScene: windowScene)
            window.rootViewController = UIHostingController(rootView: aView)
            self.window = window
            window.makeKeyAndVisible()
        }
    }
    
    func toBView() {
        let bView = BView()
        window?.rootViewController = UIHostingController(rootView: bView)
    }

}
1

There are 1 answers

0
davidev On BEST ANSWER

Asperi already stated the problem.. you are setting BView as root level. Actually changing that, shouldn't be a big problem.

But back to your question why does the NavigationLink won't work anymore. Thats because ViewA, which contains the NavigationView is not in the RootLevel anymore. Hence you will need to provide a new NavigationView, but only and only when BView is the root view.

So inside BView, add a parameter isRootView, which you will set only to true when you call it from your SceneDelegate

struct BView: View {
    init(isRootView: Bool = false) {
        print("BView init")
        self.isRootView = isRootView
    }
    
    var isRootView : Bool = false

    var body: some View {
        if isRootView {
            NavigationView {
                NavigationLink(destination: CView()) {
                        Text("This is View B, now go to View C.")
                }
            }
        }
        else
        {
            NavigationLink(destination: CView()) {
                    Text("This is View B, now go to View C.")
            }

        }
    }
}

And here the call from SceneDelegate

func toBView() {
    let bView = BView(isRootView: true)
    window?.rootViewController = UIHostingController(rootView: bView)
}