Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>Here is a code that does custom animation both for back button and when you call <code>popRootViewController:</code> method.</p> <p>It's a class that extends <code>UINavigationViewController</code> which by itself contradicts Apple's docs also it assigns private variable using KVO, which might stop working as soon as engineers change <code>UINavigationController</code> class so use it a t your own risk.</p> <pre><code>#import "MyNavigationController.h" @interface MyNavigationController () &lt;UINavigationBarDelegate&gt; { // Flag that we will use to avoid collisions between navgiation bar // when we call popViewControllerAnimated: method directly BOOL _isPopping; } - (UIViewController *)myPopViewControllerAniamted:(BOOL)animated; @end @implementation MyNavigationController - (id)init { self = [super init]; if (!self) return nil; // We can't intercept delegation of the original navigation bar, // we have to replace it with our own, by assigning new instance to // the private _navigationBar vairable UINavigationBar *navigationBar = [[UINavigationBar alloc] init]; navigationBar.delegate = self; [self setValue:navigationBar forKey:@"_navigationBar"]; return self; } // This is the delegate method called when you're about to pop navigation item - (BOOL)navigationBar:(UINavigationBar *)navigationBar shouldPopItem:(UINavigationItem *)item { // If we're in the process of popping items we don't want to reenter if (!_isPopping) { [self myPopViewControllerAniamted:YES]; } return YES; } // Similarly we have to override popToRootViewControllerAnimated: // The only difference would be that we use not previous view as a // target for the transfition, but the very first view - (UIViewController *)popViewControllerAnimated:(BOOL)animated { return [self myPopViewControllerAniamted:animated]; } // Our custom popping method - (UIViewController *)myPopViewControllerAniamted:(BOOL)animated { _isPopping = YES; // If we got here, we have at least two view controllers in the stack UIViewController *currentViewController = self.topViewController; if (animated &amp;&amp; self.viewControllers.count &gt; 1) { UIView *currentView = currentViewController.view; UIViewController *previousViewController = [self.viewControllers objectAtIndex:self.viewControllers.count - 2]; UIView *previousView = previousViewController.view; previousView.alpha = 0.0; [currentView.superview insertSubview:previousView belowSubview:currentView]; // I use UIView just for the sake of the simplicity of this example // In case of core animation you will have to deal with delegates // to trigger view controller popping when animation finishes [UIView animateWithDuration:0.33 delay:0.0 options:UIViewAnimationOptionCurveEaseInOut animations:^{ currentView.alpha = 0.0; previousView.alpha = 1.0; } completion:^(BOOL finished) { [super popViewControllerAnimated:NO]; _isPopping = NO; }]; } else { [super popViewControllerAnimated:NO]; _isPopping = NO; } return currentViewController; } @end </code></pre> <p>Once again, it was done purely as exercise of what is possible, I would highly recommend reading <a href="http://developer.apple.com/library/ios/#featuredarticles/ViewControllerPGforiPhoneOS/Introduction/Introduction.html" rel="nofollow">UIViewController guide</a>, probably <a href="http://developer.apple.com/library/ios/#documentation/UIKit/Reference/UIViewController_Class/Reference/Reference.html#//apple_ref/doc/uid/TP40006926-CH3-SW81" rel="nofollow">Container View Controller</a> can satisfy you needs as a designated way of customizing view controller behaviour.</p> <p>Hope it helps!</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload