Find out if user pressed the back button in uinavigationcontroller?

IphoneObjective C

Iphone Problem Overview


When a view loads, i want to see if it's because the user pressed the back button. How can i check this?

Iphone Solutions


Solution 1 - Iphone

The best solution I've found to detect a UINavigationController's back button press (pre-iOS 5.0) is by verifying that the current view controller is not present in the in the navigation controller's view controller stack.

It is possibly safer to check this condition in - (void)viewDidDisappear:(BOOL)animated as logically, by the time that method is called it would be extremely likely that the view controller was removed from the stack.

Pre-iOS 5.0:

- (void)viewWillDisappear:(BOOL)animated
{
    [super viewWillDisappear:animated];
    
    if (![[self.navigationController viewControllers] containsObject:self]) {
        // We were removed from the navigation controller's view controller stack
        // thus, we can infer that the back button was pressed
    }
}

iOS 5.0+ you can use -didMoveToParentViewController:

- (void)didMoveToParentViewController:(UIViewController *)parent
{
    // parent is nil if this view controller was removed
}

Solution 2 - Iphone

in your viewWillDisappear method check

- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];

    if ([self isMovingFromParentViewController]) {
      //specific stuff for being popped off stack
    }
}

This is only for post iOS 5

Solution 3 - Iphone

UINavigationController has a delegate property that issues delegate callbacks. Please see the iOS reference here.

The delegate doesn't have a "back button pressed" callback, but instead it tells you when something is going to appear on the navigation stack. When you press back, you are "popping" the top view controller off the stack, so it will tell you that the view is about to appear. I think this is the callback you'd be looking for.

You could have some simple logic to check if it's the view controller that's "interested", and then you could send a notification, et al.

Solution 4 - Iphone

For the sake of completeness, mix of two most upvoted answers (1, 2) in Swift:

override func willMoveToParentViewController(parent: UIViewController?) {
    super.willMoveToParentViewController(parent)
    if parent == nil {
        // view controller is popping
    }
}

Solution 5 - Iphone

This is a slightly different scenario, but I thought the solution might help others out.

In my situation, I had a UINavigationController within a UIPopoverController. I needed to detect whether the user clicked the back button, or clicked outside of the popover. To do this I checked the visibleViewController property in viewWillDisappear. If the view controller is still the visibleViewController when closing, then the popover is being closed by another means. If the view controller is not the visibleViewController when closing, then the back button was pressed.

- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];

    if (self.navigationController.visibleViewController != self) {
        <Do something since we're closing using something else>
    } else {
        <Do something since we're closing because of the back button>
    }
}

I tried using zach's solution, but isMovingFromParentViewController returns true for both cases.

I verified this works in iOS 5+

I hope this helps.

Solution 6 - Iphone

Create a custom back bar button and set the target,

Step 1: Add these methods to your class

- (void)backButtonClicked :(id)sender{
    [self.navigationController popViewControllerAnimated:YES];
}

- (void)addBackBarButton{
    UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
    button.frame = CGRectMake(0, 0, 55, 35);
    [button setTitle:@"back" forState:UIControlStateNormal];
    [button addTarget:self action:@selector(backButtonClicked:) forControlEvents:UIControlEventTouchUpInside];
    UIBarButtonItem *customBarItem = [[UIBarButtonItem alloc] initWithCustomView:button];
    self.navigationItem.leftBarButtonItem = customBarItem;
}

Step 2: Call [self addBackBarButton]; in viewDiDLoad method

You will get the action in backButtonClicked method. You can play around with it the way you want.

Cheers!

Solution 7 - Iphone

The only way to do this so you know for sure that it was the back button is to create a custom button. If you don't know how to do that, check out this tutorial. It won't look exactly like the normal back button, but close. If you need more help, post a comment

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAndrewView Question on Stackoverflow
Solution 1 - IphoneAndrewView Answer on Stackoverflow
Solution 2 - IphonezachView Answer on Stackoverflow
Solution 3 - IphonemakdadView Answer on Stackoverflow
Solution 4 - IphonederpoliukView Answer on Stackoverflow
Solution 5 - IphoneMatt BeckerView Answer on Stackoverflow
Solution 6 - IphoneaTozView Answer on Stackoverflow
Solution 7 - IphoneAndrewView Answer on Stackoverflow