Ios 在自定义转换中调用completeTransition:后,导航栏将进行调整

Ios 在自定义转换中调用completeTransition:后,导航栏将进行调整,ios,cocoa-touch,uikit,ios7,Ios,Cocoa Touch,Uikit,Ios7,我的目标是为用户提供从的缩放模式转换,类似于启动应用程序时跳板图标的放大 显示的视图控制器可以正确放大,但导航栏在状态栏下的位置错误。调用[transitionContext completeTransition:finished]后,此位置将得到更正;。如何从过渡开始就纠正它 这是错误的屏幕记录:(故障出现在记录的第6秒) UIViewControlleranimated转换代码: - (void)animateTransition:(id<UIViewControllerContext

我的目标是为用户提供从的缩放模式转换,类似于启动应用程序时跳板图标的放大

显示的视图控制器可以正确放大,但导航栏在状态栏下的位置错误。调用[transitionContext completeTransition:finished]后,此位置将得到更正;。如何从过渡开始就纠正它

这是错误的屏幕记录:(故障出现在记录的第6秒)

UIViewControlleranimated转换代码:

- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext
{
    UIViewController *fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
    UIViewController *toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
    UIView *container = [transitionContext containerView];

    CGPoint viewCenter = self.view.center;
    CGSize viewSize = self.view.frame.size;
    CGSize controllerSize = toViewController.view.frame.size;

    CGFloat controllerFromX = viewCenter.x - (controllerSize.width / 2);
    CGFloat controllerFromY = viewCenter.y - (controllerSize.height / 2);

    CGAffineTransform transform = CGAffineTransformMakeTranslation(controllerFromX, controllerFromY);
    transform = CGAffineTransformScale(transform, viewSize.width / controllerSize.width, viewSize.height / controllerSize.height);

    if (self.reverse) {
        [container insertSubview:toViewController.view belowSubview:fromViewController.view];
    } else {
        toViewController.view.transform = transform;
        [container addSubview:toViewController.view];
    }

    [UIView animateKeyframesWithDuration:ZoomTransitioningDuration 
                                   delay:0 
                                 options:0 
                              animations:^{
                if (self.reverse) {
                    fromViewController.view.alpha = 0.0f;
                    fromViewController.view.transform = transform;
                } else {
                    toViewController.view.transform = CGAffineTransformIdentity;
                }
        } 
                              completion:^(BOOL finished) {
                [transitionContext completeTransition:finished];
        }];
}
-(void)animateTransfion:(id)transitionContext
{
UIViewController*fromViewController=[transitionContext ViewControllerWorky:UITransitionContextFromViewControllerKey];
UIViewController*toViewController=[transitionContext ViewControllerWorky:UITransitionContextToViewControllerKey];
UIView*容器=[transitionContext containerView];
CGPoint viewCenter=self.view.center;
CGSize viewSize=self.view.frame.size;
CGSize controllerSize=toViewController.view.frame.size;
CGFloat controllerFromX=viewCenter.x-(controllerSize.width/2);
CGFloat controllerFromY=viewCenter.y-(controllerSize.height/2);
CGAffineTransform transform=CGAffineTransformMakeTransform(controllerFromX,controllerFromY);
transform=CGAffineTransformScale(transform,viewSize.width/controllerSize.width,viewSize.height/controllerSize.height);
如果(自反转){
[container insertSubview:toViewController.view below子视图:fromViewController.view];
}否则{
toViewController.view.transform=转换;
[container addSubview:toViewController.view];
}
[UIView animateKeyframesWithDuration:ZoomTransitionDuration
延迟:0
选项:0
动画:^{
如果(自反转){
fromViewController.view.alpha=0.0f;
fromViewController.view.transform=转换;
}否则{
toViewController.view.transform=CGAffineTransformity;
}
} 
完成:^(布尔完成){
[transitionContext completeTransition:完成];
}];
}

我已经找到了一个解决方案,尽管它相当粗糙。在动画开始之前,我必须手动调整导航栏帧:

if (self.reverse) {
    [container insertSubview:toViewController.view belowSubview:fromViewController.view];
} else {
    toViewController.view.transform = transform;
    [container addSubview:toViewController.view];

    // fix navigation bar position to prevent jump when completeTransition: is called
    if ([toViewController isKindOfClass:[UINavigationController class]]) {
        UINavigationController* navigationController = (UINavigationController*) toViewController;
        UINavigationBar* bar = navigationController.navigationBar;
        CGRect frame = bar.frame;
        bar.frame = CGRectMake(frame.origin.x, frame.origin.y + 20.0f, frame.size.width, frame.size.height);
    }
}

问题在于,在将目标视图控制器的视图插入容器之前,您正在设置转换

切换顺序应能解决此问题:

if (self.reverse) {
    [container insertSubview:toViewController.view belowSubview:fromViewController.view];
} else {
    [container addSubview:toViewController.view];
    toViewController.view.transform = transform;
}

见第4点。由于您在将导航控制器的视图作为子视图插入之前应用了转换,因此布局引擎认为导航栏不在窗口的顶部边缘,因此不需要调整以避免出现状态栏。

这仍然是一个难题,基于Ondřej Mirtes的一个,但是如果你有一个通话状态栏,并且你在iOS8上,效果会更好

if([toViewController isKindOfClass:[UINavigationController class]]) { 
  UINavigationController *navCtrl = (UINavigationController *)toViewController;
  UINavigationBar *navBar = navCtrl.navigationBar;
  if(navBar.frame.origin.y == 0 && navBar.frame.size.height == 44) {
    navBar.frame = CGRectMake(0, 0, navBar.frame.size.width, fmin(44 + [UIApplication sharedApplication].statusBarFrame.size.height, 64)); 
  }
}

但是仍然很难看:/

首先将toViewControllerView添加到ContainerView,然后设置toViewControllerView转换,如下所示

[container addSubview:toViewController.view]

toViewController.view.transform=转换


这将解决问题。

您不能调整相应视图的y原点吗?当我这样做时,状态栏下方的区域是黑色的,而不是绿色的(整个控制器向下移动)。self.view从何而来?演示视图控制器也是动画控制器吗?能否再次公开视频?目前还没有一个好的、非黑客的解决方案,因此观看视频会很有帮助。问题是,这只是第一次解决问题。稍后再次显示同一视图控制器将导致导航栏过低20像素。这可以正常工作,但不适用于彩色导航栏。bar.frame=CGRectMake(frame.origin.x,frame.origin.y,frame.size.width,frame.size.height+20.0f);好得多;)但它仍然使子视图出现问题。对我来说也是如此!谢谢那篇文章的第四点真是天赐良机。