UIViewController在设置动画时的方向错误

时间:2011-03-08 15:01:54

标签: ios uikit core-animation

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

为了在这样做时有一些不错的过渡,我正在使用这样的缩放效果:

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

这非常有效,除了在进行动画制作时,无论当前的设备方向如何,新视图始终如同纵向模式一样。动画完成后,视图会自动定位。

我错过了什么?

我尝试过的事情:

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

奇怪的是,如果我在方法开头的窗口上执行recursiveDescription,则窗口框架被定义为大小为768x1024(即纵向),而其内部的视图为748x1024,但是[0,-1,1,0,0,0]的变换(这是指旋转还是什么?不应该是身份变换吗?)

2 个答案:

答案 0 :(得分:3)

UIWindow不会轮播。它内部有一个旋转视图(正如你所见)。但是,在这种情况下,我认为问题可能是您的视图已经在此处进行了转换,并且您需要与它进行连接,而不是像在setTransform:调用中那样替换它。

你不应该向应用代表询问窗口,你应该从视图中获取窗口(self.view.window)。

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

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

答案 1 :(得分:2)

我终于弄清楚出了什么问题。由于帧不是真实属性而是一种计算的,基于视图边界和视图变换的值,我需要在设置与当前视图相同的变换后设置帧,并在再次设置变换之前设置动画的初始状态。此外,我需要设置的帧与当前视图当前使用的帧相同,因为它考虑了窗口方向(或者没有,正如Rob Napier指出的那样)

所以,不用多说了,这是工作代码:

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