Präsentieren von ViewController mit NavigationViewController schnell

73

Ich habe das System "NavigationViewController -> MyViewController" und möchte MyViewController programmgesteuert in einem dritten View Controller präsentieren. Das Problem ist, dass ich nach der Präsentation keine Navigationsleiste in MyViewController habe. Können Sie mir helfen?

var VC1 = self.storyboard.instantiateViewControllerWithIdentifier("MyViewController") as ViewController
self.presentViewController(VC1, animated:true, completion: nil)
Yury Alexandrov
quelle

Antworten:

208

Durch das Aufrufen wird presentViewControllerder Ansichtscontroller modal außerhalb des vorhandenen Navigationsstapels dargestellt. Es ist nicht in Ihrem UINavigationController oder einem anderen enthalten. Wenn Ihr neuer Ansichts-Controller über eine Navigationsleiste verfügen soll, haben Sie zwei Hauptoptionen:

Option 1. Schieben Sie den neuen Ansichts-Controller auf Ihren vorhandenen Navigationsstapel, anstatt ihn modal darzustellen:

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

Option 2. Betten Sie Ihren neuen Ansichts-Controller in einen neuen Navigations-Controller ein und präsentieren Sie den neuen Navigations-Controller modal:

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)

Beachten Sie, dass diese Option nicht automatisch eine Schaltfläche "Zurück" enthält. Sie müssen selbst einen engen Mechanismus einbauen.

Welches für Sie am besten geeignet ist, ist eine Frage zum Design der Benutzeroberfläche, aber normalerweise ist klar, was am sinnvollsten ist.

Stefandouganhyd
quelle
1
Wie kann ich dafür sorgen, dass der neue Ansichts-Controller von rechts nach links und nicht von unten nach oben gebracht wird? Vielen Dank
vincwng
4
OK. Aber wie kann ich das Modal schließen?
Peter Kreinz
MyViewController (ViewController) ist bereits über StoryBoard mit NavigationController verbunden. Dann funktioniert die Option 1, nicht, die derzeitige Navigationssteuerung ohne Navigationsleiste!
Kiran
Schreiben Sie diese Codezeile, wenn Sie die doppelte Navigationsleiste sehen. navController.isNavigationBarHidden = true
Nij
15

SWIFT 3

let VC1 = self.storyboard!.instantiateViewController(withIdentifier: "MyViewController") as! MyViewController
let navController = UINavigationController(rootViewController: VC1)
self.present(navController, animated:true, completion: nil)
Maksim Kniazev
quelle
13

Meine Navigationsleiste wurde nicht angezeigt, daher habe ich in Swift 2 iOS 9 die folgende Methode verwendet

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)
Vinod Joshi
quelle
2

Die akzeptierte Antwort ist großartig. Dies ist keine Antwort, sondern nur eine Illustration des Problems.

Ich präsentiere einen viewController wie folgt:

in vc1:

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

in vc2:

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

Wie 'Stefandouganhyd' gesagt hat: "Es ist nicht in Ihrem UINavigationController oder einem anderen enthalten."

neue Lösung:

func returnFromVC2() {
    dismiss(animated: true, completion: nil)
}
Honig
quelle
1

Ich habe eine Erweiterung von UIViewController und eine Struktur verwendet, um sicherzustellen, dass meine aktuelle Ansicht aus den Favoriten angezeigt wird

1.Strukt für einen globalen Bool

struct PresentedFromFavourites {
static var comingFromFav = false}

2.UIVeiwController-Erweiterung: Modal dargestellt wie in der zweiten Option durch "Stefandouganhyd - Option 2" und Lösen des Rückens

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
    }

}}
Atka
quelle