【问题标题】:Presenting a UINavigationController in a custom modal在自定义模式中呈现 UINavigationController
【发布时间】:2014-01-24 22:16:11
【问题描述】:

我正在尝试从 UINavigationController 呈现 UINavigationController。我正在使用新的 iOS 7 transitioningDelegate 东西,它工作得很好......除了导航栏开始很高,然后在动画结束时缩小。我假设它会缩小,因为条形图没有触及屏幕顶部,但为什么它一开始就很高?我可以防止这种情况吗?

这是动画代码:

- (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext {

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

    if (toViewController.isBeingPresented) {
        [self presentModalView:toViewController.view fromView:fromViewController.view inContainerView:containerView withTransitionContext:transitionContext];
    } else {
        [self dismissModalView:fromViewController.view fromView:toViewController.view withTransitionContext:transitionContext];
    }
}

- (void)presentModalView:(UIView*)modalView fromView:(UIView*)presentationView inContainerView:(UIView*)containerView withTransitionContext:(id<UIViewControllerContextTransitioning>)transitionContext {
    [containerView addSubview:modalView];
    presentationView.userInteractionEnabled = NO;

    modalView.layer.cornerRadius = 5;
    modalView.clipsToBounds = YES;

    CGRect finalFrame = CGRectInset(presentationView.frame, 10, 20);
    modalView.frame = CGRectOffset(finalFrame, 0, CGRectGetHeight(presentationView.frame));

    [UIView animateWithDuration:animationDuration animations:^{
        modalView.frame = finalFrame;
        presentationView.alpha = 0.2;
    } completion:^(BOOL finished) {
        [transitionContext completeTransition:YES];
    }];
}

【问题讨论】:

  • 有没有机会也可以添加收缩部分的 GIF?只是想知道到底发生了什么?
  • @TylerFlemingCloutier 是的。我不在我的机器旁,但当我拿到它时我会。基本上,在制作动画时,它的高度太高了 20 像素,完成后它立即(非动画)变为正常大小(想想 iOS 6 导航栏的高度)。

标签: ios objective-c animation ios7 uinavigationcontroller


【解决方案1】:

我有办法解决这个问题。

来自http://blog.jaredsinclair.com/post/61507315630/wrestling-with-status-bars-and-navigation-bars-on-ios-7,4号:

UINavigationController 将根据一组相当奇怪且未记录的约束将其 UINavigationBar 的高度更改为 44 点或 64 点。如果 UINavigationController 检测到其视图框架的顶部与其 UIWindow 的顶部在视觉上是连续的,则它会绘制高度为 64 磅的导航栏。如果其视图的顶部与 UIWindow 的顶部不连续(即使仅相差一个点),则它以“传统”方式绘制其导航栏,高度为 44 点。此逻辑由 UINavigationController 执行,即使它是应用程序视图控制器层次结构中的多个子级。没有办法阻止这种行为。

因此,您的问题是UINavigationController 在动画开始时检测到它的视图框架与UIWindow 的顶部是连续的。这是因为当您将modalView 添加为containerView 的子视图时,modalView 的框架为{0,0,0,0}。因为这个框架在视觉上与UIWindow 的顶部是连续的,所以UINavigationController 以64 磅的高度绘制它的UINavigationBar。动画完成后,导航控制器的新框架不再与窗口顶部连续,绘制高度为 44 的导航栏。

一种解决方案是在设置框架后将导航控制器的视图添加到容器视图中。像这样,

 - (void)presentModalView:(UIView*)modalView fromView:(UIView*)presentationView inContainerView:(UIView*)containerView withTransitionContext:(id<UIViewControllerContextTransitioning>)transitionContext {
    presentationView.userInteractionEnabled = NO;

    modalView.layer.cornerRadius = 5;
    modalView.clipsToBounds = YES;

    CGRect finalFrame = CGRectInset(presentationView.frame, 10, 20);
    modalView.frame = CGRectOffset(finalFrame, 0, CGRectGetHeight(presentationView.frame));
    [containerView addSubview:modalView];

    [UIView animateWithDuration:animationDuration animations:^{
        modalView.frame = finalFrame;
        presentationView.alpha = 0.2;
    } completion:^(BOOL finished) {
        [transitionContext completeTransition:YES];
    }];
}

这应该可以解决您的问题,因为导航栏将始终以 44 磅的高度在整个动画中绘制。我不知道有什么方法可以将导航栏的高度保持在 64 磅,因为这会导致导航控制器误以为它与窗口的顶部是连续的。

【讨论】:

  • 你是个天才!非常感谢!
  • 谢谢泰勒!顺便说一句,任何使用 view.center 动画过渡的人都需要注意。不要..使用 view.frame
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-02
相关资源
最近更新 更多