如何应用复杂的CALayer转换更改?

时间:2015-06-22 17:59:54

标签: ios core-animation calayer catransform3d cadisplaylink

我需要一个UIView的复杂连续动画,其中涉及设置需要计算的CATransform3D旋转和平移属性,因此标准动画无法选择。

我转向使用CALayer动画。并且有这个:

self.displayLink = [self.window.screen displayLinkWithTarget:self selector:@selector(update:)];
[self.displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];

- (void)update:(CADisplayLink*)sender
{
    CGFloat elapsedTime = sender.timestamp - self.lastTimestamp;
    self.lastTimestamp = sender.timestamp;

    self.rotation += elapsedTime * 0.1;  // Factor determines speed.

    // This is just example for SO post; the real animation is more complicated!
    CATransform3D transform;
    transform = CATransform3DMakeRotation(self.rotation, 1.0, 0.0, 0.0);
    self.imageLayer.transform = transform;
}

此处self.imageLayerCALayer,其contents已设置了图片,并作为子图层添加到我的基本视图中。

它确实旋转了一下'但不是连续的,有时它似乎会停止或向后旋转一点。

似乎经常分配新的transform没有任何影响,因为self.rotation值会增加更多。添加[self setNeedsDisplay]没有帮助。

我对CALayer做得不多,所以我想我错过了一些非常基本的东西。试图找到它已有一段时间了,但我发现的所有例子似乎都远离我想要的。

1 个答案:

答案 0 :(得分:4)

当您创建自己的图层然后修改其属性时,它会隐式动画它们(请参阅“Animating Simple Changes to a Layer’s Properties”。您没有看到预期的更改,因为Core Animation正在动画更改而不是立即应用它们

您需要禁用隐式动画。有几种方法可以禁用它;见“Changing a Layer’s Default Behavior”。或search stack overflow for “disable implicit animations”。这是一种方式:

NSDictionary *actions = @{ @"transform": [NSNull null] };
self.imageLayer.actions = actions;

只需执行一次,即可创建imageLayer