Take the 2-minute tour ×

Is it possible to cancel a segue in the prepareForSegue: method?

I want to perform some check before the segue, and if the condition is not true (in this case, if some UITextField is empty), display an error message instead of performing the segue.

share|improve this question
add comment

4 Answers

up vote 117 down vote accepted

In iOS 6 it´s possible: You have to implement the method

- (BOOL)shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(id)sender 

in your view controller. You do your validation there, and if it´s OK then return YES; if it´s not the return NO; and the prepareForSegue is not call.

share|improve this answer
FYI, if the segue is triggered programmatically by calling [self performSegueWithIdentifier:@"segueIdentifier" sender:nil]; shouldPerformSegueWithIdentifier will never get called. –  The dude Aug 6 '13 at 9:20
@Thedude thanks for pointing this out. Was tracking down an issue and it wasn't hitting my breakpoint. For anyone curious, you just need to call this method wrapped in an if statement to get the same result. –  jpittman Dec 12 '13 at 23:15
add comment

Note: the accepted answer is the best approach if you can target iOS 6. For targeting iOS 5, this answer will do.

I don't believe it is possible to cancel a segue in prepareForSegue. I would suggest moving your logic to the point that the performSegue message is first sent.

If you are using Interface Builder to wire up a segue directly to a control (e.g. linking a segue directly to a UIButton), then you can accomplish this with a bit of refactoring. Wire the segue to the view controller instead of a specific control (delete the old segue link, and then control-drag from the view controller itself to the destination view controller). Then create an IBAction in your view controller, and wire the control to the IBAction. Then you can do your logic (check for empty TextField) in the IBAction you just created, and decide there whether or not to performSegueWithIdentifier programatically.

share|improve this answer
If the segue is to a popover controller, you do not want a second tap of the button to create another popover controller; the correct thing to do in this case is to dismiss the popover. Your answer allows for this proper behavior. If you wire it directly from the button in the storyboard, I don't see anyway to get the proper behavior. –  wcochran Apr 19 '12 at 15:29
After several frustrating hours of trying to get multiple segue-based popovers to play nicely together, I gave up and got rid of the popover seques in favor of this solution. It actually uses less code. –  mpemburn Feb 19 '13 at 16:36
add comment

Alternatively, it's somewhat bad behavior to offer a button that a user shouldn't press. You can leave the segue wired as stands, but start with the button disabled. Then wire the UITextField's "editingChanged" to an event on the view control ala

- (IBAction)nameChanged:(id)sender {
    UITextField *text = (UITextField*)sender;
    [nextButton setEnabled:(text.text.length != 0)];
share|improve this answer
add comment

Similar to Kaolin's answer is to leave the seque wired to the control but validate the control based on conditions in the view. If you're firing on table cell interaction then you also need to set the userInteractionEnabled property as well as disabling the stuff in the cell.

For instance, I've got a form in a grouped table view. One of the cells leads to another tableView that acts as a picker. Whenever a control is changed in the main view I call this method

    if (micSwitch.on)
        filterPickerCell.textLabel.enabled = YES;
        filterPickerCell.detailTextLabel.enabled = YES;
        filterPickerCell.userInteractionEnabled = YES;
        filterPickerCell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
        filterPickerCell.textLabel.enabled = NO;
        filterPickerCell.detailTextLabel.enabled = NO;
        filterPickerCell.userInteractionEnabled = NO;
        filterPickerCell.accessoryType = UITableViewCellAccessoryNone;

share|improve this answer
add comment

Your Answer


