CATransition不尊重iPad上的方向变化

时间:2012-11-13 19:03:25

标签: page-curl catransition

我有一个有效的页面卷曲。问题是iPad的旋转。该应用程序仅在横向上运行,并支持左侧和右侧。如果iPad“风景正确”,那么卷曲就会发生在右下方。如果我旋转iPad,视图会按预期旋转,但现在当我尝试卷曲发生在左上角时。我已经添加了一个通知,告诉我它何时旋转并尝试更改动画子类型但没有骰子。

   -(IBAction)curlViewUp
{
    uiv_help.alpha = 1.0;

    [UIView animateWithDuration:1.0
                     animations:^{
                         CATransition *animation = [CATransition animation];
                         [animation setDelegate:self];
                         [animation setDuration:0.7];
                         [animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
                         animation.type = @"pageCurl";
                         animation.subtype = curlDirection;
                         animation.fillMode = kCAFillModeForwards;
                         animation.endProgress = 0.20;
                         [animation setRemovedOnCompletion:NO];
                         [self.view.layer addAnimation:animation forKey:@"pageCurlAnimation"];
                         [self.view addSubview:uiv_help];
                         ;}
     ];
}

-(IBAction)curlViewDown
{
    uiv_help.alpha = 0.0;

    [UIView animateWithDuration:1.0
                     animations:^{
                         CATransition *animation = [CATransition animation];
                         [animation setDelegate:self];
                         [animation setDuration:0.7];
                         [animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut]];
                         animation.type = @"pageUnCurl";
                         animation.subtype = curlDirection;
                         animation.fillMode = kCAFillModeForwards;
                         animation.startProgress = 0.80;
                         [animation setRemovedOnCompletion:YES];
                         [self.view.layer addAnimation:animation forKey:@"pageUnCurlAnimation"];
                         //[self.view removeFromSuperview];
                         [uiv_help removeFromSuperview];
                         ;}
     ];

}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return (interfaceOrientation == UIInterfaceOrientationLandscapeLeft | interfaceOrientation == UIInterfaceOrientationLandscapeRight);
}

-(void)checkRotation:(NSNotification*)notification
{
    UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
    if(orientation == UIInterfaceOrientationLandscapeLeft)
    {
        NSLog(@"UIInterfaceOrientationLandscapeLeft");

        curlDirection = @"fromRight";
    } else if (orientation == UIInterfaceOrientationLandscapeRight) {
        NSLog(@"UIInterfaceOrientationLandscapeRight");

        curlDirection = @"fromRight";
    }
}

1 个答案:

答案 0 :(得分:3)

您的pagecurl不随设备一起旋转。

这是因为它的视图不随设备旋转而旋转..

是因为它的视图是视图层次结构中最顶层的视图。

我无法在任何地方找到这方面的文档(其他人可以将其挖出来吗?),但是视图层次结构中最外层的视图不会旋转。我想这是因为正是这个视图的责任是旋转其他所有东西(或者更确切地说,这个视图应用了某种旋转变换)。

这是一个简单的验证方法,只需记录视图的框架和边界,并观察旋转时会发生什么。

这里我们处于肖像模式。我已经在self.view中设置了一个子视图,其尺寸相同。

self.view frame {{0, 20}, {768, 1004}}
self.view bounds {{0, 0}, {768, 1004}}
self.view center {384, 522}
--------
self.subview frame {{0, 0}, {768, 1004}}
self.subview bounds {{0, 0}, {768, 1004}}
self.subview center {384, 502}

现在让我们旋转到风景

self.view frame {{20, 0}, {748, 1024}}
self.view bounds {{0, 0}, {1024, 748}}
self.view center {394, 512}
--------
self.subview frame {{0, 0}, {1024, 748}}
self.subview bounds {{0, 0}, {1024, 748}}
self.subview center {512, 374}

您将看到内部子视图正确报告宽度为1024,高度为748px。 但外观刚刚变得怪异。它的帧报告宽度为748,高度为1024,好像它仍然是纵向(添加了状态栏20px)。但它的界限告诉我们它是景观。

我们显然不希望依赖报告此类奇怪结果的视图的几何属性。我想这与Apple的警告相关,如果它已经受到除身份变换之外的任何变换的影响,则不应该引用视图的帧。

解决方案是将页面管理视图嵌入到另一个最外层视图中。创建一个新视图,将其称为self.subview(或其他),并将其作为self.view的唯一子项添加到视图层次结构中。将其大小调整为与self.view相同的矩形。在self.subview上操作而不是self.view。

更改此行:

[self.view.layer addAnimation:animation forKey:@"pageCurlAnimation"];

[self.subview.layer addAnimation:animation forKey:@"pageCurlAnimation"];

并更改此行:

[self.view.layer addAnimation:animation forKey:@"pageUnCurlAnimation"];

为:

[self.subview.layer addAnimation:animation forKey:@"pageUnCurlAnimation"];

然后你的卷发将按照你的预期运作,因为你正在将它们应用到一个按预期旋转的视图。

您可以在不更改代码的情况下获得相同的结果,但将viewController嵌入到UINavigationViewController中。在这种情况下,NavViewController的视图是不旋转的最外面的视图。所以你的self.view将会轮换。

更新

UIWindow* mWindow = [[UIApplication sharedApplication] keyWindow];
UIView *topView = [[mWindow subviews] lastObject];
NSLog("%@",topView);


topView <UILayoutContainerView: 0x71eb450; 
frame = (0 0; 748 1024); 
transform = [0, 1, -1, 0, 0, 0];     
autoresize = W+H; gestureRecognizers = <NSArray: 0x71f8a30>; 
layer = <CALayer: 0x71eb540>>

注意转换。