Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to stop a UIViewController from being popped from a UINavigationController's stack when the backBarButtonItem is tapped?

I have a UINavigationController with a root view controller and then I push a UIViewController onto the navigation controller's stack. When the user taps the backBarButtonItem I'd like to be able to have an alert view pop up if there are certain conditions met and cancel the pop of the view controller. For example, the user can make certain selections but some combination of them may be invalid so I want to notify them to make changes.

I know that I can prevent the user from making an invalid combination or have an alert view pop up when the invalid combination is selected but I'd rather not do that. The user may be changing selections and may be aware that a certain combination is invalid but I'd rather let them select something that makes the combination invalid then go change something else (and notify them if they haven't made changes before trying to go to the previous screen). For example, if I prevent them from selecting something that makes an invalid combination then they may have to scroll up on a screen, change something, then scroll back down instead of making a selection then scrolling up and changing something.

Using viewWillDisappear: doesn't work because, although I can produce an alert view, I cannot figure out a way to prevent the pop from occurring. The alert view displays but the view controller still pops and they are back to the root view controller (with the alert view displaying).

Is there a way to prevent the pop from occurring? If not, is this something worth filing a bug report about or is this unnecessary and/or esoteric?

like image 778
yabada Avatar asked Apr 23 '10 22:04

yabada


People also ask

What is Interactivepopgesturerecognizer?

The gesture recognizer responsible for popping the top view controller off the navigation stack.

What is a navigation controller for?

NavController manages app navigation within a NavHost . Apps will generally obtain a controller directly from a host, or by using one of the utility methods on the Navigation class rather than create a controller directly. Navigation flows and destinations are determined by the navigation graph owned by the controller.

How do I get the most popular view controller?

In addition, you can check for UINavigationController and ask for its topViewController or even check for UITabBarController and ask for selectedViewController . This will get you the view controller that is currently visible to the user.


3 Answers

You can replace the back button with your own that calls the method you want in loadView

cancelButton = [[UIBarButtonItem alloc] initWithTitle:@"Cancel" 
                                    style:UIBarButtonItemStyleBordered 
                                    target:self
                                    action:@selector(onCancelButtonSelected:)];



self.navigationItem.leftBarButtonItem = cancelButton;

then later

-(void)onCancelButtonSelected:(id)sender {

if (!hasSavedProduct) 
{
    cancelAlert = [[UIAlertView alloc] initWithTitle:@"Product not saved" 
                                             message:@"Exit without saving?" 
                                            delegate:self 
                                   cancelButtonTitle:@"Exit" 
                                   otherButtonTitles:@"Save", 
                                                        nil];
    [cancelAlert show];
    [cancelAlert release];
}

then let them go

- (void)alertView:(UIAlertView *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {



if ([cancelAlert isEqual:actionSheet]) 
{
    if (buttonIndex == 0)
    {
        NSLog(@"Fine. Exiting without saving");


        [self.navigationController popViewControllerAnimated:YES];
    }
    else
    {
        NSLog(@"Save here"); 

    }
}
like image 66
jvcleave Avatar answered Nov 12 '22 18:11

jvcleave


This sounds like something more appropriate for a Modal View Controller than it is for a View Controller on a Navigation stack.

If you're married to doing it on the stack though, it'd be nice if you could do this with UINavigationControllerDelegate, but you can't.

Is it possible to set the Back button to disabled, until the entries are valid? Perhaps when the user tries to enter something, but it's invalid, near the top of the View you have a Label animate into place with red text that tells the user they need to fix it. Meanwhile the back button is disabled and it's re-enabled after they make corrections.

Or get really creative with how your UI controls work to ensure that the user can never enter bad data.

like image 26
bpapa Avatar answered Nov 12 '22 18:11

bpapa


Let them go back, just don't save anything unless it's completely valid. That's typically the approach Apple takes.

like image 26
Jamie Pinkham Avatar answered Nov 12 '22 18:11

Jamie Pinkham