Navigation Bar jumping when presenting view controller via UIPresentationController subclass
Asked Answered
B

2

6

I'm building an iOS 8 app and using UIPresentationController to present a view controller in a custom way. (see my previous question about this here: Replicating the style of the iOS Mail App's Compose Function).

The issue I'm having is that when I present the controller, the navigation bar starts off as 64 points tall and then jumps/shrinks back to 44 once its presentation is finished. My guess is that the view controller realizes it is not covering the status bar and so it shrinks itself down once it comes to its final resting position. I'd like for the navigation bar to be 44 points tall the entire time and not jump/shrink.

The image below is what the view controller looks like at the end of the presentation. It is also what I want it to look like the entire time. Any thoughts on how to keep the navigation bar at 44 points the entire time?

enter image description here

UPDATE (3/24/2015):

I referenced a blog post from a while back to find some more information on this issue. Basically, UINavigationController draws its navigation bar either 64 or 44 points tall depending on if its view's frame is matched up with the app's window or not. So I need some way of telling the navigation controller that its final resting position will not be lined up with the window, and that the nav bar should be drawn 44 points tall.

http://blog.jaredsinclair.com/post/61507315630/wrestling-with-status-bars-and-navigation-bars-on

Butterfield answered 18/3, 2015 at 13:44 Comment(0)
B
2

Finally found an answer to this question. It's explained in this previous stack overflow post:

Navigation bar gets adjusted after calling completeTransition: in custom transition

Thank you for not making me use my hard earned rep to start a bounty!

Butterfield answered 24/3, 2015 at 20:26 Comment(0)
S
1

I had an issue a bit like yours, where the navigation bar would resize after [transitionContext completeTransition:YES] was called, based on visual contiguity of the navigationBar's frame sharing a border with the UIWindow's top. My navigation bar was nowhere near the top, so it resized itself to 44px instead of the normal "extend-under-the-status-bar" 64px. To get around this, I simply completed the transition before I animated my toViewController's alpha and position. That is, once everything was positioned properly to be animated in, I called completeTransition: to let the navigationController adjust itself while invisible. So far, this hasn't had any unintended side-effects, and the additional alpha in, move frame animations still continue after you completeTransition.

Here is my animateTransition: method in my presentation animator class that conforms to <UIViewControllerAnimatedTransitioning>

    UIViewController *toViewController          = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
    UIViewController *fromViewController        = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];

    UIViewController *presentedViewController   = self.presenting ? toViewController : fromViewController;
    UIView *containerView                       = [transitionContext containerView];

    NSTimeInterval animationDuration            = [self transitionDuration:transitionContext];

    if (self.presenting) {
        containerView.alpha = 0.0;
        presentedViewController.view.alpha = 0.0;
        [containerView addSubview:presentedViewController.view];
        [UIView animateWithDuration:animationDuration delay:0 options:kNilOptions animations:^{
            containerView.alpha = 1.0;
        } completion:^(BOOL finished) {
            presentedViewController.view.frameTop += 20;
            //I complete the transition here, while my controller's view is still invisible, 
            // but everything is in its proper place.  This effectively positions everything 
            // for animation, while also letting the navigation bar resize itself without jarring visuals.
            [transitionContext completeTransition:YES];
            //But we're not done quite yet...
            [UIView animateWithDuration:animationDuration delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
                presentedViewController.view.frameTop -= 20;
                presentedViewController.view.alpha = 1.0;
            } completion:nil];
        }];
    }

    if (!self.presenting) {
        [UIView animateWithDuration:animationDuration delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
            presentedViewController.view.alpha = 0.0;
            presentedViewController.view.frameTop += 20;
        } completion:^(BOOL finished) {
            [UIView animateWithDuration:animationDuration delay:0 options:kNilOptions animations:^{
                containerView.alpha = 0.0;
            } completion:^(BOOL done) {
                [transitionContext completeTransition:YES];
            }];
        }];
    }

Hope this helps anyone that finds themselves in my position!

Second answered 4/8, 2015 at 19:7 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.