Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

segue.destinationViewController is nil when presenting UINavigationController modal

I have an UICollectionView and when the user presses a cell, I present another view controller in a UINavigationController modally using a storyboard.

- (void)collectionView:(UICollectionView *)collectionView
didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
    [self performSegueWithIdentifier:@"editBookIPad"
                                      sender:indexPath];
}


- (void)prepareForSegue:(UIStoryboardSegue *)segue
                 sender:(id)sender
{
    // Did not include code for other segues, but I check which is the current one properly
    UINavigationController *dest = segue.destinationViewController; // This is nil!
    dest.modalPresentationStyle = UIModalPresentationFormSheet;
    DetailsViewController *detailsVC = (id)[dest topViewController];
    detailsVC.stack = self.stack;
    detailsVC.editingMode = 1;
    detailsVC.bookToEdit = [self.fetchedResultsController objectAtIndexPath:sender];
    [self.collectionView deselectItemAtIndexPath:sender
                                        animated:YES];
}

Storyboard

Now, my problem is that segue.desinationViewController returns nil (as the comment in the code snippet says).

Just for debugging, I changed the UINavigationController to another view controller and I had no problem. I don't know if changing from modal to push as transition style will help since it's impossible to push a UINavigationController (a crash happens that says it is so).

I cleaned the project and the build folder and restarted my computer (and hence Xcode).

This is what it looks like when running the app:

Screenshot of problem

When searching for similar problems I found nothing about this. Most other questions were about properties being set on the destination view controller being nil (such as this).

I use Xcode 5.1.1 and have iOS 7.0 as development target.

Edit1

The same problem happens in all parts of my app now (everywhere a UINavigationController is presented modally). However, it only happens on some occasions, but every time segue.destinationViewController is still nil.

Edit2

I replaced the prepareForSegue code with this (doing it manually):

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Storyboard"
                                                     bundle:nil];
UINavigationController *navCon = [storyboard instantiateViewControllerWithIdentifier:@"AllBooksVCDetails"]; // The problematic navigation controller
navCon.modalPresentationStyle = UIModalPresentationFormSheet;
BKSBookDetailsViewController *detailsVC = (id)[navCon topViewController];
detailsVC.stack = self.stack;
detailsVC.editingMode = 1;
detailsVC.bookToEdit = [self.fetchedResultsController objectAtIndexPath:indexPath];
[self presentViewController:navCon
                   animated:YES
                 completion:nil];
[self.collectionView deselectItemAtIndexPath:indexPath
                                    animated:YES];

And this works. So I think the problem lies in the storyboard somehow.

like image 963
user3956212 Avatar asked Jun 07 '15 15:06

user3956212


People also ask

What is segue in Objective C?

A segue defines a transition between two view controllers in your app's storyboard file. The starting point of a segue is the button, table row, or gesture recognizer that initiates the segue. The end point of a segue is the view controller you want to display.


3 Answers

I had same problem when embedding the viewcontroller inside a NavigationController.

 override public func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {

        let destinationVC = segue.destinationViewController as! UINavigationController
        let nextViewController = destinationVC.viewControllers[0] as! SecondViewController

        nextViewController.someProperty = someValue
    }

This link helps me:

https://www.andrewcbancroft.com/2015/06/02/access-sub-controllers-from-a-uinavigationcontroller-in-swift/

like image 93
mmendez Avatar answered Oct 01 '22 17:10

mmendez


I also encountered this problem using swift, but after 1 hour, observed that instead of segue.destinationViewController I used sender.destinationViewController that messed all things. Are you sure you are using segue not sender?

like image 39
iamandrewluca Avatar answered Oct 01 '22 15:10

iamandrewluca


Problem is when embedding UIViewController inside a UINavigationController. A variant of S. Matsepura's answer where "ShowView" is the identifier of the segue (if you have more than one):

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "ShowView" {
        if let nc = segue.destination as? UINavigationController, let vc = nc.topViewController as? MyViewController {
            vc.var = "value"
        }
    }
}
like image 21
Json Avatar answered Oct 01 '22 15:10

Json