与CATransform3DMakeRotation奇怪的观点

时间:2011-11-27 17:31:59

标签: iphone objective-c transform rotation perspective

我对CATransform3DMakeRotation有一个奇怪的问题。当旋转的视图位于超视图的中心时,它看起来像这样:

Valid XHTML http://i1183.photobucket.com/albums/x467/Laurin_Koppenwallner/Bildschirmfoto2011-11-27um181544.png

这应该是它的样子。但是,当它位于超级视图中的其他位置时,例如,在左下角,它看起来像这样:

Valid XHTML http://i1183.photobucket.com/albums/x467/Laurin_Koppenwallner/Bildschirmfoto2011-11-27um181627.png

请注意,它向右倾斜。当它在右下角时发生同样的事情,只是它向左倾斜。是否有某种方法可以使它在所有时间和每个位置都倾斜?实现此转换的代码如下:

    CALayer *layer = view.layer;

    CATransform3D aTransform = CATransform3DIdentity;
    float zDistance = 1000;
    aTransform.m34 = 1.0 / -zDistance;  

    self.view.layer.sublayerTransform = aTransform;


    CABasicAnimation *rotateAnim = [CABasicAnimation animationWithKeyPath:@"transform"];
    rotateAnim.fromValue= [NSValue valueWithCATransform3D:CATransform3DMakeRotation(0, 0, 0, 0)];
    rotateAnim.duration=0.12;
    rotateAnim.toValue=[NSValue valueWithCATransform3D:CATransform3DMakeRotation(20*M_PI/180, 1, 0, 0)];

    rotateAnim.removedOnCompletion = NO;
    rotateAnim.fillMode = kCAFillModeForwards;
    [layer addAnimation:rotateAnim forKey:@"rotateAnim"];

1 个答案:

答案 0 :(得分:3)

您已经在superview的图层应用了透视图,这就是您所获得的。如果您想要基于各个子图层的透视图(不考虑整体透视图),则必须单独应用透视图。例如:

CALayer *layer = view.layer;

CATransform3D aTransform = CATransform3DIdentity;
CGFloat zDistance = 2000.;
aTransform.m34 = 1.0 / -zDistance;  

CABasicAnimation *rotateAnim = [CABasicAnimation animationWithKeyPath:@"transform"];

rotateAnim.fromValue= [NSValue valueWithCATransform3D:aTransform];
aTransform = CATransform3DRotate(aTransform, 20*M_PI/180, 1, 0, 0);;
rotateAnim.duration=0.12;
rotateAnim.toValue=[NSValue valueWithCATransform3D:aTransform];
layer.transform = aTransform;

[layer addAnimation:rotateAnim forKey:@"rotateAnim"];

在此示例中,我在图层的m34fromValue中应用了透视(toValue)。然后,这将为您提供相对于站在图层本身前方的观察者的视角。你的原始代码有一个观察者站在视图的中心前面,所以你得到一些偏斜的视角。

我在这里做了一些其他的小改动。我通常把观察者放在2000而不是1000.我发现1000的视角往往超过预期(除非你积极寻求强有力的观点)。根据您的问题,您可能希望完全摆脱视角。不要只是出于习惯而应用它。

更重要的是,我改变了你最后应用动画的方式。使用removedOnCompletion=NOkCAFillModeForwards比将动画应用到模型(layer.transform=aTransform)并让动画正常删除要复杂得多。特别是,使用removedOnCompletion=NO意味着以后对layer.transform的请求将始终返回旧值,而不是当前值。如果您将更多动画应用于此图层,也会使事情变得复杂。这就是默认情况下完成时删除动画的原因。