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

Posted

技术标签:

【中文标题】通过 UIPresentationController 子类呈现视图控制器时导航栏跳转【英文标题】:Navigation Bar jumping when presenting view controller via UIPresentationController subclass 【发布时间】:2015-03-18 13:44:17 【问题描述】:

我正在构建一个 ios 8 应用程序并使用 UIPresentationController 以自定义方式呈现视图控制器。 (请参阅我之前的问题:Replicating the style of the iOS Mail App's Compose Function)。

我遇到的问题是,当我展示控制器时,导航栏开始时高度为 64 点,然后在其展示完成后跳转/收缩回 44。我的猜测是视图控制器意识到它没有覆盖状态栏,因此一旦到达最终的静止位置,它就会收缩自己。我希望导航栏始终保持 44 点高而不是跳跃/收缩。

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

更新(2015 年 3 月 24 日):

我参考了不久前的一篇博客文章,以找到有关此问题的更多信息。基本上,UINavigationController 根据其视图的框架是否与应用程序的窗口匹配,将其导航栏绘制为 64 或 44 点高。所以我需要某种方式告诉导航控制器它的最终静止位置不会与窗口对齐,并且导航栏应该被绘制为 44 磅高。

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

【问题讨论】:

【参考方案1】:

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

Navigation bar gets adjusted after calling completeTransition: in custom transition

感谢您没有让我利用我来之不易的代表开始赏金!

【讨论】:

【参考方案2】:

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

这是我的演示动画师类中的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];
            ];
        ];
    

希望这可以帮助任何发现自己处于我位置的人!

【讨论】:

以上是关于通过 UIPresentationController 子类呈现视图控制器时导航栏跳转的主要内容,如果未能解决你的问题,请参考以下文章

下拉框多选框单选框 通过TagHelper绑定数据

酶:测试孩子通过安装渲染失败,但通过浅时通过

java是通过值传递,也就是通过拷贝传递——通过方法操作不同类型的变量加深理解

通过代码进行 Spring 配置与通过注释进行配置

如何理解“不要通过共享内存来通信,而应该通过通信来共享内存”?

通过邮递员通过 API 使用 Rails 主动存储上传文件(.pdf、.jpg 等)? (不通过 Rails 视图)