在UIViewControlleranimation的时候错误的方向

为了使用UISplitViewController,我从一个视图控制器导航到另一个视图控制器时replace了我的窗口根控制器。

为了在这样做的时候有一些很好的转换,我使用了这样的缩放效果:

MyOtherViewController *controller = [[MyOtherViewController alloc] initWithNibName:@"MyOtherView" bundle:nil]; UIWindow *window = ((MyAppDelegate *)[[UIApplication sharedApplication] delegate]).window; controller.view.frame = [window frame]; controller.view.transform = CGAffineTransformMakeScale(0.01,0.01); controller.view.alpha = 0; [window addSubview:controller.view]; [UIView animateWithDuration:0.2 animations:^{ controller.view.transform = CGAffineTransformMakeScale(1,1); controller.view.alpha = 1.0; } completion:^(BOOL finished) { if (finished) { [self.view removeFromSuperview]; window.rootViewController = controller; } }]; 

而且这个效果很好,除了在做animation的时候,无论当前的设备方向如何,新的视图总是被定位为纵向模式。 当animation完成时,视图正确定向。

我错过了什么?

我试过的东西:

  • 把我的新控制器视图作为UIWindow的唯一子视图
  • 在animation开始之前使我的新控制器成为根视图控制器

奇怪的是,如果我在我的方法的开始处的窗口上执行recursion描述,窗口框架被定义为具有768×1024(即,纵向)的尺寸,并且其内部的视图是748×1024,但是具有[0,-1,1,0,0,0](这是否意味着一个旋转或什么?不应该是身份转换?)

UIWindow不会旋转。 它有一个旋转的视图里面(如你所见)。 不过,在这种情况下,我认为问题很可能是您的视图已经在此处进行了转换,您需要将它连接起来,而不是像在setTransform: calls中那样replace它。

你不应该问窗口的应用程序委托,你应该从视图( self.view.window )获取窗口。

如果您在任何时候将视图附加到窗口本身,而不是将其放置在旋转视图中,则需要通过遍历层次结构来了解要匹配的视图的有效变换:

 - (CGAffineTransform)effectiveTransform { CGAffineTransform transform = [self transform]; UIView *view = [self superview]; while (view) { transform = CGAffineTransformConcat(transform, [view transform]); view = [view superview]; } return transform; } 

我终于明白了什么是错的。 由于框架不是一个真实的属性,而是一种计算的,基于视图边界和视图变换的值,我需要设置相同的变换作为当前视图,并再次设置变换之前设置框架设置animation的初始状态。 此外,我需要设置的框架与当前视图当前使用的框架相同,因为它正在考虑窗口方向(或者像Rob Napier指出的那样缺less窗口方向)

所以,不要紧张,这是工作代码:

 MyOtherViewController *controller = [[MyOtherViewController alloc] initWithNibName:@"MyOtherView" bundle:nil]; UIWindow *window = [[UIApplication sharedApplication] keyWindow]; CGAffineTransform t = self.view.transform; controller.view.transform = t; controller.view.frame = self.view.frame; controller.view.transform = CGAffineTransformScale(t,.01,.01);; [window addSubview:controller.view]; controller.view.alpha = 0; [UIView animateWithDuration:0.2 animations:^{ controller.view.transform = t; controller.view.alpha = 1.0; } completion:^(BOOL finished) { if (finished) { [self.view removeFromSuperview]; window.rootViewController = controller; [controller release]; } }];