/CCTBackButtonAction

A helper class to "catch" NavigationBar back button action

Primary LanguageObjective-CMIT LicenseMIT

Problem

You want to show an alert view when user taps the back button on a navigation bar, and prevent the navigating if user decides to stay on the top view controller.

There are quite some questions on this topic over at stackoverflow: link1, link2, link3.

This project tries to solve this problem with a reusable solution, which is based on two facts:

  • The method navigationBar:shouldPopItem: in UINavigationController will be called, while UINavigationController is not declared to conform the UINavigationBarDelegate.
  • The item passed to navigationBar:shouldPopItem: will vary, depending on how you pop the top view controller. If you navigate by tapping the back button, the item will be navigationItem of the "current" top controller. If you navigate by calling popViewControllerAnimated:, the item will be navigationItem of the "previous" controller.

This code has not been tested. There are not many lines of code, please use until you've reviewed it.

For more information, see this post.

Use CCTBackButtonActionHelper

  • Include CCTBackButtonActionHelper.h and CCTBackButtonActionHelper.m in your project.

  • Create a subclass of UINavigationController, import CCTBackButtonActionHelper.h, implement navigationBar:shouldPopItem: and create instances with this subclass:

    #import "CCTBackButtonActionHelper.h"

    - (BOOL)navigationBar:(UINavigationBar *)navigationBar shouldPopItem:(UINavigationItem *)item {
        BOOL should = [[CCTBackButtonActionHelper sharedInstance] navigationController:self
                                                                   navigationBar:navigationBar
                                                                   shouldPopItem:item];
        if (!should) {
            return NO;
        }

        return [super navigationBar:navigationBar shouldPopItem:item];
    }
  • In the view controller, implement cct_navigationBar:willPopItem: and show alert view there:
    - (void)cct_navigationBar:(UINavigationBar *)navigationBar willPopItem:(UINavigationItem *)item {
        UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Are You Sure?"
                                                          message:nil
                                                         delegate:self
                                                cancelButtonTitle:@"No"
                                                otherButtonTitles:@"Yes", nil];
        [alertView show];
    }
  • In the same view controller, implement alert view delegate and pop view controller manually.
    - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
        if (alertView.cancelButtonIndex == buttonIndex) {
            return;
        }

        [self.navigationController popViewControllerAnimated:YES];
    }