【问题标题】:Weird Perspective With CATransform3DMakeRotationCATransform3DMakeRotation 的奇怪视角
【发布时间】:2012-01-07 10:03:57
【问题描述】:

我在使用 CATransform3DMakeRotation 时遇到了一个奇怪的问题。当旋转后的视图位于父视图的中心时,它看起来像这样:

这就是它应该的样子。但是,当它位于 superview 的其他位置时,比如在左下角,它看起来像这样:

请注意,它向右倾斜。当它在右下角时也会发生同样的事情,只是它向左倾斜。有没有办法让它在任何时候和每个位置都以它应该的方式倾斜?实现这种变换的代码如下:

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

【问题讨论】:

  • 您可能没有正确构建 CATransform3D,很可能是因为忘记了平移和旋转相互影响。发布用于生成转换的代码。

标签: iphone objective-c transform rotation perspective


【解决方案1】:

您已经在超级视图的层应用了透视,这就是您所得到的。如果您想要基于各个子层的透视图(不考虑整体透视图),那么您必须将透视图单独应用于它们。例如:

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

在这个例子中,我在图层的fromValuetoValue 中都应用了透视图(m34)。然后,这为您提供了相对于站在图层本身前面的观察者的视角。您的原始代码有一个观察者站在视图中心的前面,因此您会得到一些倾斜的视角。

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多