presenting ViewController with NavigationViewController swift
Asked Answered
F

5

81

I have system "NavigationViewController -> MyViewController", and I programmatically want to present MyViewController inside a third view controller. The problem is that I don't have navigation bar in MyViewController after presenting it. Can you help me?

var VC1 = self.storyboard.instantiateViewControllerWithIdentifier("MyViewController") as ViewController
self.presentViewController(VC1, animated:true, completion: nil)
Firth answered 22/8, 2014 at 9:51 Comment(0)
C
234

Calling presentViewController presents the view controller modally, outside the existing navigation stack; it is not contained by your UINavigationController or any other. If you want your new view controller to have a navigation bar, you have two main options:

Option 1. Push the new view controller onto your existing navigation stack, rather than presenting it modally:

let VC1 = self.storyboard!.instantiateViewControllerWithIdentifier("MyViewController") as! ViewController
self.navigationController!.pushViewController(VC1, animated: true)

Option 2. Embed your new view controller into a new navigation controller and present the new navigation controller modally:

let VC1 = self.storyboard!.instantiateViewControllerWithIdentifier("MyViewController") as! ViewController
let navController = UINavigationController(rootViewController: VC1) // Creating a navigation controller with VC1 at the root of the navigation stack.
self.present(navController, animated:true, completion: nil)

Bear in mind that this option won't automatically include a "back" button. You'll have to build in a close mechanism yourself.

Which one is best for you is a human interface design question, but it's normally clear what makes the most sense.

Chiarra answered 22/8, 2014 at 12:52 Comment(6)
How can I make it so that the new view controller will be brought from Right to Left, rather than from Bottom up? ThanksPhosphene
Ok. But how can i close the modal?Ethben
MyViewController (ViewController) already linked to NavigationController via StoryBoard. Then the Option 1, Not works, Its present navigation controller without navigation bar!Angadresma
Write this line of code if you see double NavigationBar. navController.isNavigationBarHidden = trueFewer
@PeterKreinz probably a bit late, but it might help somebody. Using XCode 13, and a simulator of an iPhone 7 with iOS 11.4 I found the above solution worked but wasn't displaying VC1 modally, however when I ran the same code on a actual iPhone the view was displayed modallyBurgoyne
The second option does not work with iPhone 12 or iPhone XR. It works for iPhone 7 and iPod 7th Generation. Is there a solution which would work universally?Castoff
J
17

SWIFT 3

let VC1 = self.storyboard!.instantiateViewController(withIdentifier: "MyViewController") as! MyViewController
let navController = UINavigationController(rootViewController: VC1)
self.present(navController, animated:true, completion: nil)
Janise answered 26/11, 2016 at 11:13 Comment(0)
G
15

My navigation bar was not showing, so I have used the following method in Swift 2 iOS 9

let viewController = self.storyboard?.instantiateViewControllerWithIdentifier("Dashboard") as! Dashboard

// Creating a navigation controller with viewController at the root of the navigation stack.
let navController = UINavigationController(rootViewController: viewController)
self.presentViewController(navController, animated:true, completion: nil)
Greeson answered 24/9, 2015 at 11:22 Comment(0)
D
2

The accepted answer is great. This is not answer, but just an illustration of the issue.

I present a viewController like this:

inside vc1:

func showVC2() {
    if let navController = self.navigationController{
        navController.present(vc2, animated: true)
    }
}

inside vc2:

func returnFromVC2() {
    if let navController = self.navigationController {
        navController.popViewController(animated: true)
    }else{
        print("navigationController is nil") <-- I was reaching here!
    }
}

As 'stefandouganhyde' has said: "it is not contained by your UINavigationController or any other"

new solution:

func returnFromVC2() {
    dismiss(animated: true, completion: nil)
}
Diaspora answered 13/6, 2019 at 19:26 Comment(0)
R
1

I used an extension to UIViewController and a struct to make sure that my current view is presented from the favourites

1.Struct for a global Bool

struct PresentedFromFavourites {
static var comingFromFav = false}

2.UIVeiwController extension: presented modally as in the second option by "stefandouganhyde - Option 2 " and solving the back

extension UIViewController {
func returnToFavourites()
{
    // you return to the storyboard wanted by changing the name
    let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil)
    let mainNavigationController = storyBoard.instantiateViewController(withIdentifier: "HomeNav") as! UINavigationController
    // Set animated to false
    let favViewController = storyBoard.instantiateViewController(withIdentifier: "Favourites")
    self.present(mainNavigationController, animated: false, completion: {
        mainNavigationController.pushViewController(favViewController, animated: false)
    })

}
// call this function in viewDidLoad()
// 
func addBackToFavouritesButton()
{
    if PresentedFromFavourites.comingFromFav
    {
        //Create a button
        // I found this good for most size classes
        let buttonHeight = (self.navigationController?.navigationBar.frame.size.height)! - 15
        let rect = CGRect(x: 2, y: 8, width: buttonHeight, height: buttonHeight)
        let aButton = UIButton(frame: rect)
        // Down a back arrow image from icon8 for free and add it to your image assets  
        aButton.setImage(#imageLiteral(resourceName: "backArrow"), for: .normal)
        aButton.backgroundColor = UIColor.clear
        aButton.addTarget(self, action:#selector(self.returnToFavourites), for: .touchUpInside)
        self.navigationController?.navigationBar.addSubview(aButton)
        PresentedFromFavourites.comingFromFav = false
    }

}}
Resinoid answered 1/8, 2017 at 13:57 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.