Ios – Programmatically create navigation controller with back button

iosswiftuibarbuttonitemuinavigationcontroller

I haven't been able to figure something out in swift in my AppDelegate. I've been working on this little problem for weeks (in the background, not continuously) with lots of googling. I must be missing something.

When a remote notification comes in to my iOS app I'd like to modally present the View appropriate for the message, with a UINavigationController that has a Back button. The idea is that when the user is finished dealing with the notification, they can press "Back" and go back to where they were. I can't get a "Back" button to show up in my navigation controller programmatically.

Not all of my existing views are embedded in navigation controllers. So, rather than finding an existing UINavigationController in the stack, I've been creating a new UINavigationController and trying to set it up and present it like this:

    let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
    var mvc = mainStoryboard.instantiateViewControllerWithIdentifier("MyViewIdentifier") as! MySpecialViewController

    /* here is where I setup the necessary variables in the mvc view controller, using data from the remote message.  You don't need to see all that */

    /* this seems to work, I do get what looks to be a navigation controller */
    let newNavController = UINavigationController(rootViewController: mvc)

    /* this part doesn't work, I don't get a "Back" button */
    let btn = UIBarButtonItem(title: "back", style: UIBarButtonItemStyle.Done, target: mvc, action: "backPressed")
    newNavController.navigationItem.leftBarButtonItem = btn

    /* this block seems to work.  The idea is to work through the hierarchy of any modal presentations
    until we get to the screen that is actually showing right now.  I'm not    
    sure this will work in all situations, but it seems to work in my app's hierarchy. */
    var currentViewController = self.window!.rootViewController
    while currentViewController?.presentedViewController != nil {
        currentViewController = currentViewController?.presentedViewController
    }

    /* this I suppose shows my new view controller modally, except without
    the "back" button it's hard to be sure the navigation controller is even there. */
    currentViewController?.presentViewController(newNavController, animated: true, completion: nil)

I do have a method called "backPressed" in the relevant view controller.

Any clues as to why the navigation bar button isn't showing up?

Edit: I knew that backBarButtonItem only shows up when we aren't at the top of the stack. But, leftBarButtonItem should show up even if we're at the top of the stack?

Best Answer

Here is simple example for you which can set navigation bar Programmatically from first View:

if let resultController = storyboard!.instantiateViewControllerWithIdentifier("SecondView") as? SecondView {
    let navController = UINavigationController(rootViewController: resultController) // Creating a navigation controller with resultController at the root of the navigation stack.
    self.presentViewController(navController, animated:true, completion: nil)
}

If you wan to add back button into that navigation then use this code into SecondView.swift class:

override func viewDidLoad() {
super.viewDidLoad()

   let backButton = UIBarButtonItem(title: "Back", style: UIBarButtonItemStyle.Plain, target: self, action: "goBack")
   navigationItem.leftBarButtonItem = backButton

}

func goBack(){
    dismissViewControllerAnimated(true, completion: nil)
}

If you want to do all of this from firstView then here is your code:

@IBAction func btnPressed(sender: AnyObject) {


if let resultController = storyboard!.instantiateViewControllerWithIdentifier("SecondView") as? SecondView {
    resultController.navigationItem.leftBarButtonItem = UIBarButtonItem(title: "Back", style: UIBarButtonItemStyle.Plain, target: self, action: "goBack")
    let navController = UINavigationController(rootViewController: resultController) // Creating a navigation controller with VC1 at the root of the navigation stack.
    self.presentViewController(navController, animated:true, completion: nil)
    }
}

func goBack(){
    dismissViewControllerAnimated(true, completion: nil)
}

Hope this will help you.