Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get UINavigationBar delegate to allow "back", with a nice animation

Scenario on an iPhone:

The user taps the back button, the UINavigationBar delegate method (implemented in a subclass of UINavigationController) returns YES, like this:

- (BOOL)navigationBar:(UINavigationBar *)navigationBar shouldPopItem:(UINavigationItem *)item
{
    // Verify stuff...

    return YES;
}

Now, according to the docs, it's the app's responsibility to keep the nav bar and the contents in sync, and the place to do that is in the delegate method

- (void)navigationBar:(UINavigationBar *)navigationBar didPopItem:(UINavigationItem *)item

The problem is, that didPopItem is only called after the nav bar's pop animation sequence is finished, so if I call [self popViewControllerAnimated: NO] there, the net result is that first the nav bar slides back, then the contents.

And that just looks wrong.

If I call the navigation controller's pop... in the delegate shouldPop... method, I get an error message to the effect that I am overlapping animations, and the final state is not clean.

So my question is, is there another way to get the UINavigationController to change contents, preferably with a nice animation in sync with the nav bar's, but without creating confusion between the nav bar and the navigation controller?

The target OS is iOS 4.2 and later.

I am aware that I could just create another left button in place of the back button, but I found it cleaner to use a delegate, plus, I get a "real" back button, which is what I want.

like image 592
Monolo Avatar asked May 10 '12 21:05

Monolo


2 Answers

If you are using a UINavigationController, you do not need to manage this yourself. You will save yourself a lot of trouble by simply using the UINavigationController. It will take care of popping the content view along with the navigation bar items.

like image 147
BrickWall10 Avatar answered Oct 31 '22 11:10

BrickWall10


Try this:

Imagine you have viewControllerA and viewControllerB. viewControllerA is the first one and doesn't need a navigationBar and viewControllerB does.

On the method viewWillAppear in viewControllerA put the code:

[self.navigationController setNavigationBarHidden:YES animated:YES];

and when popping the viewControllerB you do so with animation. Both animations will be in sync automagically.

Don't know if this is valid for iOS4.2

like image 35
pedros Avatar answered Oct 31 '22 11:10

pedros