我在CATransform3DMakeRotation中遇到了一个奇怪的问题。当旋转视图位于超级视图的中心时,它看起来像这样:
这就是它的外观。但是,当它在超级视图中的其他位置时,例如在左下角,它看起来像这样:
请注意,它向右倾斜。当它位于右下角时,也会发生同样的事情,只是它向左倾斜。是否有某种方法可以使其始终和在任何位置倾斜?实现此转换的代码如下:
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"];
最佳答案
您已将透视图应用于超级视图的图层,这就是您所获得的。如果要基于各个子层的透视图(不考虑整体透视图),则必须将透视图单独应用于它们。例如:
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"];
在此示例中,我在图层的
m34
和fromValue
中都应用了透视图(toValue
)。然后,您可以相对于站在图层本身前面的观察者进行透视。您的原始代码有一个观察者站在视图的中心,因此您获得了一些倾斜的透视图。我在这里做了一些其他小的更改。我通常将观察者的角度设置为2000,而不是1000。我发现以1000为视角的角度通常比期望的要大(除非您正在积极寻求更强的角度)。根据您的问题,您可能希望完全摆脱透视。不要只是出于习惯而应用它。
更重要的是,我改变了您最后如何应用动画。使用
removedOnCompletion=NO
和kCAFillModeForwards
使事情变得比仅将动画应用于模型(layer.transform=aTransform
)并正常删除动画要复杂得多。特别地,使用removedOnCompletion=NO
意味着以后对layer.transform
的请求将始终返回旧值,而不是当前值。如果将更多的动画应用到该层,这也会使事情变得复杂。这就是为什么默认是在完成后删除动画的原因。