Ios 在自定义转换中调用completeTransition:后,导航栏将进行调整
我的目标是为用户提供从的缩放模式转换,类似于启动应用程序时跳板图标的放大 显示的视图控制器可以正确放大,但导航栏在状态栏下的位置错误。调用[transitionContext completeTransition:finished]后,此位置将得到更正;。如何从过渡开始就纠正它 这是错误的屏幕记录:(故障出现在记录的第6秒) UIViewControlleranimated转换代码:Ios 在自定义转换中调用completeTransition:后,导航栏将进行调整,ios,cocoa-touch,uikit,ios7,Ios,Cocoa Touch,Uikit,Ios7,我的目标是为用户提供从的缩放模式转换,类似于启动应用程序时跳板图标的放大 显示的视图控制器可以正确放大,但导航栏在状态栏下的位置错误。调用[transitionContext completeTransition:finished]后,此位置将得到更正;。如何从过渡开始就纠正它 这是错误的屏幕记录:(故障出现在记录的第6秒) UIViewControlleranimated转换代码: - (void)animateTransition:(id<UIViewControllerContext
- (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);好得多;)但它仍然使子视图出现问题。对我来说也是如此!谢谢那篇文章的第四点真是天赐良机。