0

I have a side menu in app so on clicking the notification I navigate to view controller but cannot navigate to other VC's as it's not showing the navigation bar.

I've done this in my App Delegate and also have a navigation controller in my storyboard.

let sb = UIStoryboard(name: "Main", bundle: nil)
        let otherVC = sb.instantiateViewController(withIdentifier: "messageview") as! MessageViewController
        window?.rootViewController = otherVC;

func application(_ application: UIApplication,didReceiveRemoteNotification userInfo: [AnyHashable: Any],fetchCompletionHandler completionHandler:@escaping (UIBackgroundFetchResult) -> Void) {

    let state = application.applicationState
    if state == .inactive || state == .background {

        let sb = UIStoryboard(name: "Main", bundle: nil)
        let otherVC = sb.instantiateViewController(withIdentifier: "messageview") as! MessageViewController
        window?.rootViewController = otherVC

        print("background")
    } else {
        print("foreground")

    }
}
shim
  • 9,289
  • 12
  • 69
  • 108

1 Answers1

2

Of course the navigation bar is removed; the view controller needs to be embedded in a navigation controller.

Try this:

let sb = UIStoryboard(name: "Main", bundle: nil)

let otherVC = sb.instantiateViewController(withIdentifier: "messageview") as! MessageViewController
// (actually, you don't need to cast to MessageViewController here; 
// the returned reference already is guaranteed to at least be a 
// UIViewController instance; you don't need more specificity in this    
// case --i.e, embed in navigation)

let navigation = UINavigationController(rootViewController: otherVC)
window?.rootViewController = navigation

Note: This will present a fresh navigation with your view controller as the root. You will not be able to "navigate back" to any other screens that normally preceed it when navigating manually from your app's initial screen.

If you need to recreate a specific location within your navigation hierarchy, you will need to instantiate all previous view controllers up to the one you want to show, and set them instantly as the contents of the navigation stack.

Dummy example:

let first = UIStoryboard(name: "First", bundle: nil).instantiateInitialViewController()
let second = UIStoryboard(name: "Second", bundle: nil).instantiateInitialViewController() 

let top = UIStoryboard(name: "Mail", bundle: nil).instantiateInitialViewController() 

let vcs = [first, second, top]

let navigation = UINavigationController()
navigation.setViewController(vcs, animated: false)

window?.rootViewController = navigation

(this example assumes each VC lives in a separate storyboard, but you can also use instantiateViewController(withIdentifier:_) if that fits your setup)

Now, you can go back to "Second" and "First" using the navigation controller's back button.

Nicolas Miari
  • 16,006
  • 8
  • 81
  • 189