Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Custom animation for UINavigationController push not rendering navbar correctly

In a custom segue, I have the following simple transition:

- (void) perform {
    UIViewController *src = (UIViewController *) self.sourceViewController;
    UIViewController *dst = (UIViewController *) self.destinationViewController;
    [UIView transitionWithView:src.navigationController.view duration:1
                       options:UIViewAnimationOptionTransitionFlipFromBottom
                    animations:^{
                        [src.navigationController pushViewController:dst animated:NO];
                    }
                    completion:NULL];
}

The content view animates fine. However, when executing the animation, the nav bar at the top has a messed up layout (buttons all crammed in the upper left corner, no title), popping into place only when the animation is finished. Anyone know what I've done wrong and how to fix it? Thanks!

like image 873
qix Avatar asked Jun 23 '12 00:06

qix


1 Answers

Figured out my problem. The original code is indeed incorrect given how the UINavigationController works and interacts with the UIViewControllers it manages. (Annoyingly stuff like what I did in the OP can be found as a solution in older SO posts.)

Here's code that works for me (with one minor quibble):

- (void) perform {
    UIViewController *src = (UIViewController *) self.sourceViewController;
    UIViewController *dst = (UIViewController *) self.destinationViewController;
    [UIView transitionFromView:src.view
                        toView:dst.view
                      duration:1
                       options:UIViewAnimationOptionTransitionFlipFromBottom
                    completion:nil];
    [UIView transitionFromView:src.navigationItem.titleView
                        toView:dst.navigationItem.titleView
                      duration:1
                       options:UIViewAnimationOptionTransitionFlipFromBottom
                    completion:nil];
    [src.navigationController pushViewController:dst animated:NO];
}

Quibble: this will animate the navbar separately from the content view, so you have two pieces flipping instead of the whole screen. I had originally tried to do:

    [UIView transitionFromView:src.navigationController.view
                        toView:dst.navigationController.view

But that fails because the 1) destination's navigationController property isn't even set yet until it's pushed onto a nav controller, and 2) even if it were I'd be referring to the same view! I forgot that

The view for a navigation controller is just a container for several other views, including a navigation bar, an optional toolbar, and the view containing your custom content...Although the content of the navigation bar and toolbar views changes, the views themselves do not...the navigation controller object builds the contents of the navigation bar dynamically using the navigation items (instances of the UINavigationItem class) associated with the view controllers on the navigation stack. To change the contents of the navigation bar, you must therefore configure the navigation items for your custom view controllers. (docs)

like image 173
qix Avatar answered Sep 28 '22 11:09

qix