Prevent Segue in Prepareforsegue Method

Prevent segue in prepareForSegue method?

It's possible in iOS 6 and later:
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 then return NO; and the prepareForSegue is not called.

Note that this method doesn't get called automatically when triggering segues programmatically. If you need to perform the check, then you have to call shouldPerformSegueWithIdentifier to determine whether to perform segue.

How can I cancel a prepareForSegue if the nested IF doesn't pass?

(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender.

This method is only Notifies the view controller that a segue is about to be performed.You can not prevent segue.The default implementation of this method does nothing. Subclasses override this method and use it to configure the new view controller prior to it being displayed.

https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIViewController_Class/#//apple_ref/occ/instm/UIViewController/performSegueWithIdentifier:sender:

check with this May be it will help

To stop segue and show alert

Swift prevent storyboard segue from happening

To check if your identifier is "createdCard" use the shouldPerformSegueWithIdentifiermethod like this:

override func shouldPerformSegueWithIdentifier(identifier: String ,sender: AnyObject?) -> Bool {

return !(identifier == "createCard" && amountOfTimes > 8)

}

IPhone: Prevent popover segue in prepareForSegue method?

As the answers to that other question point out, once you hit prepareForSegue, it's too late to cancel it. You need to prevent the segue from being invoked the second time at all, rather than trying to stop it half way through the segue process. You can accomplish this in a variety of ways, depending upon the desired behavior:

First, if you'd like a second click on the button to dismiss the popover, you could (a) remove the segue; and (b) programmatically either present the popover or dismiss it as appropriate:

  1. remove the popover segue from storyboard;
  2. give your popover view a unique identifier so you can instantiate the controller via code;
  3. make sure you have some IBOutlet or other reference to your navigation bar button (in my code sample below, it's myNavBarButton) so that you can tell your popover to be presented from that button;
  4. you might want to also change the simulated metrics for the popover view to be "freeform", because if you leave it to "inferred", Interface Builder will assume you want it to be full screen and will repeatedly resize it for you;
  5. define an ivar for your popover, e.g. UIPopoverController *_popover;;
  6. define and link IBAction for your navigation bar button that does the work of dismissing or presenting of the popover as appropriate; and
  7. make sure to define view controller with the button to be a UIPopoverControllerDelegate so that it can receive and handle the popoverControllerDidDismissPopover event.

Thus, the ARC solution might look like:

@interface MyViewController ()
{
UIPopoverController *_popover;
}
@end

@implementation MyViewController

- (void)popoverControllerDidDismissPopover:(UIPopoverController *)popoverController
{
_popover = nil;
}

- (IBAction)navbarButtonClicked:(id)sender
{
if (_popover)
{
// If the popover already is present, dismiss it

// I'm dismissing the popover here, but if you wanted to do something else,
// e.g. like do nothing, you could replace these two lines with whatever
// behavior you want if the user clicked on the button again.

[_popover dismissPopoverAnimated:YES];
_popover = nil;
}
else
{
// If the popover doesn't exist yet, let's create and present it

UIViewController *controller = [self.storyboard instantiateViewControllerWithIdentifier:@"gesturePopover"];
_popover = [[UIPopoverController alloc] initWithContentViewController:controller];
[_popover presentPopoverFromBarButtonItem:self.myNavBarButton permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
}
}

// the rest of your main view controller's implementation

@end

Second, you could alternatively just disable the navigation bar button, so you don't get popovers on top of popovers. You'll also have a nice visual indication that it's disabled. So bottom line, you can disable the button in prepareForSegue before you perform the segue and then re-enable it when the popover is dismissed. You will need to define an identifier for your segue in Interface Builder and you'll need an outlet/reference to your navigation bar button so that you can enable and disable it. It would then look like:

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:@"mySegueIdentifier"])
{
UIPopoverController *popover = [(UIStoryboardPopoverSegue *)segue popoverController];
popover.delegate = self;
self.myNavBarButton.enabled = FALSE;
}
}

- (void)popoverControllerDidDismissPopover:(UIPopoverController *)popoverController
{
self.myNavBarButton.enabled = TRUE;
}

Is there a way to stop a segue after prepareForSegue has been called

UIKit calls the delegate method shouldPerformSegueWithIdentifier:sender: before calling prepareForSegue:sender: Return NO from this method if your array is empty.

To stop segue and show alert

If your deployment target is iOS 6.0 or later

You can simply implement the shouldPerformSegueWithIdentifier:sender: method on your source view controller. Make this method return YES if you want to perform the segue, or NO if you don't.

If your deployment target is earlier than iOS 6.0

You will need to change the way your segue is connected in the storyboard and write a little more code.

First, set up the segue from the button's view controller to the destination view controller, instead of directly from the button to the destination. Give the segue an identifier like ValidationSucceeded.

Then, connect the button to an action on its view controller. In the action, perform the validation and either perform the segue or show an alert based on whether the validation succeeded. It will look something like this:

- (IBAction)performSegueIfValid:(id)sender {
if ([self validationIsSuccessful]) {
[self performSegueWithIdentifier:@"ValidationSucceeded" sender:self];
} else {
[self showAlertForValidationFailure];
}
}

How to override the prepareForSegue with multiple Segue's

Conditionally cast the different segue destination view controllers or check for the segue's identifier whichever you prefer.

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let destinationVC = segue.destination as? NoteTableViewController {
if let indexLocale = noteTableView.indexPathForSelectedRow {
destinationVC.selectionCategory = noteArray[indexLocale.row]
print(indexLocale.row)
}
} else if let weatherDestinationVC = segue.destination as? WeatherViewController {
weatherDestinationVC.delegate = self
}
}

Also, you don't have to performSegue within prepareForSegue.

How do I cancel a segue that is connected to an UIButton

Nope. You can't cancel segues that are directly linked to interface elements like your UIButton.

But there is a workaround.

  1. Remove the segue that is linked to the button
  2. Add a segue from the viewController (the one with the button) to the viewController that should be pushed. This must be a segue that is not connected to a interface element. To do this you can start the segue from the status bar. Or create the segue in the left sidebar.
  3. Select this segue, open the attributes inspector and change the Identifier of the segue (e.g. PushRedViewController)
  4. Select Xcodes assistant view, so you can see the .h file of the viewController with the button.
  5. Connect the button to an action. To do this select the button and control-drag to the .h file. Select action in the menu and name your action (e.g. redButtonPressed:)
  6. Open the implementation of your viewController
  7. change the action from step 5 to something like this:

    - (IBAction)redButtonPressed:(id)sender {
    [self performSegueWithIdentifier:@"PushRedViewController" sender:sender];
    }

How to prevent segue transition when table view is editing in Swift?

Implement shouldPerformSegue(withIdentifier:sender:) in your view controller, and have it return false if you don't want the segue to be performed.



Related Topics



Leave a reply



Submit