在自定义模式中呈现UINavigationController

时间:2014-01-24 22:16:11

标签: ios objective-c animation ios7 uinavigationcontroller

我正在尝试从UINavigationController呈现UINavigationController。我正在使用新的iOS 7 transitioningDelegate东西并且它工作得很好....除了导航栏开始高,然后在动画结束时收缩。我假设它缩小了,因为酒吧没有碰到屏幕的顶部,但为什么它开始高?我可以阻止这个吗?

Notice the bar starts tall

这是动画代码:

- (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];
    }];
}

1 个答案:

答案 0 :(得分:4)

我有解决这个问题的方法。

来自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将其UINavigationBar绘制为64点的高度。动画完成后,导航控制器的新框架不再与窗口顶部连续,并绘制高度为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点,因为这会让导航控制器误以为它与窗口顶部是连续的。