How to "cancel" a UIStoryBoardSegue

Solution 1:

If you are targeting iOS 6 or greater, then my knowledge of the cleanest way to do this is the following:

-(BOOL)shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(id)sender
{
    if([identifier isEqualToString:@"show"])
    {
        NSIndexPath *selectedRowIndex = [self.tableView indexPathForSelectedRow];
        Blocco *blocco = [self.fetchedResultsController objectAtIndexPath:selectedRowIndex];
        return [blocco meetRequiredConditions];
    }
    return YES;
}

Where there is a method

-(BOOL) meetsRequiredConditions;

Defined on your Blocco class returns YES if the "couple of things" which permit a drill-down are valid.

Solution 2:

I don't know if it is the right way to do it but I discovered a workaround.

From the storyboard I associate(control+click) a segue from the status bar in the view controller. Give the segue an ID (for example: switchSegue).

Now, from an action in your code (in my code I use a button), I call:

 [self performSegueWithIdentifier:@"switchSegue" sender:sender];

That way you can control if your segue is performed or not. Try tutorials that helped me from here and here

Hope this helps.

Solution 3:

I am using an much easier and tidy approach.

Storyboard

  1. Create two identical cell with different identifiers. Eg: "cellWithSegue" and "cellWithoutSegue".
  2. Connect the first cell ("cellWithSegue") with the segue you want to display.
  3. Do not connect the second cell with any segue.

Table View

  1. On cellForRowAtIndexPath, implement a logic to determine if the cell should be linked a segue or not.
  2. For cells that should be linked with the segue use the "cellWithSegue" identifier, for the rest the "cellWithoutSegue".

This way looks a lot easier to implement and also does not alter the way segues are supposed to work.

Solution 4:

I may be wrong here, but after struggling myself with this, I just disabled the cell's user interaction on the cells where I didn't want the seque triggered (in cellForRowAtIndexPath:). Seems to work perfectly, and it's only 1 line of code!

cell.userInteractionEnabled = NO;

Solution 5:

The easiest solution is to create manual segue in story board and use that as seen below.

[self performSegueWithIdentifier:@"loginSuccessSegue" sender:self];

Or


@Fabio: I was trying to get a solution for same kind of use-cases and I almost found a solution.

Use-cases 1. Stop segue transition conditionally 2. Change destination viewController conditionally

Solution:

Use "Custom" segue. Follow below steps to create Custom segue 1. Create a subclass of UIStoryboardSegue "MyCustomSegue.h"

@interface MyCustomSegue : UIStoryboardSegue
@end

"MyCustomSegue.m"

Override initWithIdentifier for implementing use-case 1 and 2 If you return nil, segue will be cancelled/no action will be taken You instantiate your ViewController and set that as a destination. You can set destination as your old xib file also.. that code is commented, but I ensured that will work.

@implementation MyCustomSegue
- (id)initWithIdentifier:(NSString *)identifier source:(UIViewController *)source destination:(UIViewController *)destination{

    UIStoryboard *storyBoard= [UIStoryboard storyboardWithName:@"MainStoryboard_iPhone" bundle:nil];

    UIViewController *viewController = [storyBoard instantiateViewControllerWithIdentifier:@"testIdentifier"];

    // MyViewController* viewController= [[MyViewController alloc]initWithNibName:@"MyViewController" bundle:nil];
    return [super initWithIdentifier:identifier source:source destination:viewController];
}
  1. You must override "perform".

You can implement use-case 1 here also..

- (void)perform {
    // if either source or destination is nil, stop
    if (nil == self.sourceViewController || nil == self.destinationViewController) return;
    // return; //No Action. Segue will be cancelled
    UINavigationController *ctrl = [self.sourceViewController navigationController];
    [ctrl
     pushViewController:self.destinationViewController
     animated:YES];
}

Hope this helps. Plz write if you are not clear.