Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift 3 - Push segue to navigation controller

Tags:

swift

swift3

In my storyboard I have a View Controller, I also have a Navigation Controller and another View Controller called HistoryController. The Navigation Controller and the HistroyController have a relationship "root view controller"

I have a button on my 1st View Controller and that button has a push segue to the Navigation Controller.

I have this code in the 1st View Controller to to prepare the segue:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

        if let viewController = segue.destination as? HistoryController {
            viewController.detailItem = barcodeInt as AnyObject
        }

    }

my problem is when I run my code and push the button in my first controller, I get this error:

Could not find a navigation controller for segue 'HistorySegue'. Push segues can only be used when the source controller is managed by an instance of UINavigationController.'

My question is, why am I getting this error and how can I fix it?

I have tried the following

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if let navVC = segue.destinationViewController as? UINavigationController{
            if let historyVC = navVC.viewControllers[0] as? HistoryController{
                historyVC.detailItem = barcodeInt as AnyObject
            }
        }
    }

I have also tried

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if let nav = segue.destination as? UINavigationController {
        if let vc = nav.visibleViewController as? HistoryController {
            vc.detailItem = barcodeInt as AnyObject
        }
    }
}

and I still get the same error:

Could not find a navigation controller for segue 'HistorySegue'. Push segues can only be used when the source controller is managed by an instance of UINavigationController.'
like image 534
user979331 Avatar asked Oct 19 '16 17:10

user979331


People also ask

How do I segue to navigation controller in Swift?

To create a segue between view controllers in the same storyboard file, Control-click an appropriate element in the first view controller and drag to the target view controller. The starting point of a segue must be a view or object with a defined action, such as a control, bar button item, or gesture recognizer.

How to Add navigation controller to ViewController?

Step 1: Embed root view controller inside a navigation controller. In your storyboard, select the initial view controller in your hierarchy. With this view controller selected, choose the menu item Editor -> Embed In -> Navigation Controller .

What is swift push view controller?

Pushing a view controller causes its view to be embedded in the navigation interface. If the animated parameter is true , the view is animated into position; otherwise, the view is simply displayed in its final location.

What is segue in Swift?

Swift version: 5.6. Segues are visual connectors between view controllers in your storyboards, shown as lines between the two controllers. They allow you to present one view controller from another, optionally using adaptive presentation so iPads behave one way while iPhones behave another.


2 Answers

You need to embed your source view controller in a Navigation Controller or change the segue kind from push to something else. Also, try and cast your destination controller to UINavigationController to prevent a different error after the initial one if fixed:

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if let navVC = segue.destinationViewController as? UINavigationController{
            if let historyVC = navVC.viewControllers[0] as? HistoryController{
                historyVC.detailItem = barcodeInt as AnyObject
            }
        }
    }

See if that works for you.

EDIT: Updated the code above.

like image 88
Geoherna Avatar answered Oct 30 '22 18:10

Geoherna


Your problem is not in your code, that is fine, it is in your storyboard.

If you would like to push to HistoryVC from ViewController, ViewController should be embedded in a UINavigationController, not HistoryVC (it would be embedded implicitly by it's relationship with ViewController).

The reason for this is that the VC that is pushing must be embedded in a UINavigationController, the vc that is being pushed is inherently embedded because it is added to the UINavigationController's stack.

enter image description here

If the initial ViewController is not within a UINavigationController, there is no stack for the pushed ViewController (HistoryVC) to be pushed onto. Basically, you embed your starting point for your stack (Your first ViewController) in the UINavigationController.

If you want to start a new stack a few VCs down the line you can embed the next view controller in a new UINavigationController, that however you would need to segue to modally.

like image 25
Olivier Wilkinson Avatar answered Oct 30 '22 18:10

Olivier Wilkinson