通过 UIPresentationController 子类呈现视图控制器时导航栏跳转

Navigation Bar jumping when presenting view controller via UIPresentationController subclass

我正在构建一个 iOS 8 应用程序并使用 UIPresentationController 以自定义方式呈现视图控制器。 (在此处查看我之前关于此的问题:)。

我遇到的问题是,当我展示控制器时,导航栏开始为 64 点高,然后 jumps/shrinks 在展示完成后回到 44。我的猜测是视图控制器意识到它没有覆盖状态栏,所以一旦它到达它的最终静止位置它就会缩小自己。我希望导航栏始终为 44 点高,而不是 jump/shrink.

下图是演示结束时视图控制器的样子。这也是我希望它一直看起来的样子。关于如何始终将导航栏保持在 44 点的任何想法?

更新(2015 年 3 月 24 日):

我参考了不久前的一篇博客 post 以查找有关此问题的更多信息。基本上,UINavigationController 将其导航栏绘制为 64 或 44 点高,具体取决于其视图的框架是否与应用程序的 window 匹配。所以我需要一些方法来告诉导航控制器它的最终静止位置不会与 window 对齐,并且导航栏应该绘制成 44 点高。

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

终于找到了这个问题的答案。在之前的堆栈溢出中对此进行了解释 post:

Navigation bar gets adjusted after calling completeTransition: in custom transition

感谢您没有让我用辛苦赚来的声望来开始赏金!

我遇到的问题有点像您的问题,在调用 [transitionContext completeTransition:YES] 后,导航栏会根据导航栏框架与 UIWindow 顶部共享边框的视觉连续性调整大小。我的导航栏离顶部很远,所以它自己调整为 44px 而不是正常的 "extend-under-the-status-bar" 64px。为了解决这个问题,我只是在为 toViewController 的 alpha 和位置设置动画之前完成了过渡。也就是说,一旦一切都正确定位以进行动画处理,我调用 completeTransition: 让 navigationController 在不可见时自行调整。到目前为止,这还没有产生任何意想不到的副作用,并且额外的 alpha 输入、移动帧动画仍然会在您 completeTransition.

之后继续

这是我的演示动画 class 中的 animateTransition: 方法,它符合 <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];
            }];
        }];
    }

希望这对遇到我这种情况的人有所帮助!