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
- Create two identical cell with different identifiers. Eg: "cellWithSegue" and "cellWithoutSegue".
- Connect the first cell ("cellWithSegue") with the segue you want to display.
- Do not connect the second cell with any segue.
Table View
- On cellForRowAtIndexPath, implement a logic to determine if the cell should be linked a segue or not.
- 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];
}
- 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.