Search code examples
iosobjective-cuistoryboardsegueuistoryboardsegue

iOS 6 - programmatically triggering Unwind Segue does nothing


On my app's start up, it programmatically shows a LoginViewController using a segue. The view controller is presented modally with transition set to cross dissolve. Upon successful authentication, I want to dismiss the login view by programmatically triggering an unwind segue. So I added this to my header file:

- (IBAction)unwindSegue:(UIStoryboardSegue *)segue;

now in IB I'm able to control-drag from the "File's Owner" LoginViewController to the Exit button and choose unwindSegue:. This creates a manual segue, it shows up in the Connections inspectors for the File's Owner and the Exit button correctly. I then click on the newly created Unwind segue from the scene in IB and then give it a name. If I click on the "go to" button for the unwind segue action it takes me to the declaration mentioned above.

So far so good, I then trigger this unwind segue upon successful authentication in my GCD block:

....
dispatch_async(dispatch_get_main_queue(), ^
{
    [self performSegueWithIdentifier:@"UnwindSegueIdentifier" sender:self];

    [self.spinner removeFromSuperview];
    self.spinner = nil;
});

.....and nothing happens when it runs. The spinner does get removed correctly, but there's no sign of that unwind segue executing.

A break point in the implementation of unwindSegue: never gets hit. There are no errors thrown. Nothing gets written to the console. The identifier is correct, I triple checked (otherwise it will fail anyway).

I looked at the answers here, here and here but I don't seem to have missed anything.

What I did notice though, is that Xcode thinks unwindSegue: is not linked: linked? not linked?

I'm unable to drag from the little empty circle in front of unwindSegue: and link it to the Exit button.

Any help will be appreciated.


Solution

  • If you are using a modal segue to go to your login view, all you need to go back is to call

    [self dismissViewControllerAnimated:YES completion:nil];
    

    More precisely, you should call it at the presenting controller (your first controller), but it will be forwarded if you call at at the presented controller. You can use the completion block do any required clean up. There is no need to use GCD.

    EDIT

    To answer the additional comment: I'm not really sure from your description, but it seems you've implemented the unwind action at the presented controller instead at the presenting controller. Unwind segues are to allow to do something at the caller (e.g., setting data) without an additional protocol.