在 CALayer 层次结构中组合多个 CAAnimation
Combining multiple CAAnimations in a CALayer hierarchy
我有一段相当简单的示例代码,其中我有一个由三层组成的简单层次结构;
view layer
|- base layer
|- green layer
现在我想移动基础层,同时调整绿色层的颜色,所以我添加了一个滑块来控制动画。
代码如下所示:
@implementation ViewController
- (void)loadView
{
[super loadView];
baseLayer = [CALayer layer];
[baseLayer setFrame:[[self view] frame]];
[baseLayer setBackgroundColor:[[[UIColor redColor] colorWithAlphaComponent:0.5] CGColor]];
[[[self view] layer] addSublayer:baseLayer];
greenLayer = [CALayer layer];
[greenLayer setBounds:[baseLayer bounds]];
[greenLayer setBackgroundColor:[[UIColor greenColor] CGColor]];
[baseLayer addSublayer:greenLayer];
UISlider *slider = [[UISlider alloc] initWithFrame:CGRectMake(0, CGRectGetHeight([[self view] bounds]) - 44.0f, CGRectGetWidth([[self view] bounds]), 44.0f)];
[slider addTarget:self action:@selector(sliderValueChanged:) forControlEvents:UIControlEventValueChanged];
[[self view] addSubview:slider];
CABasicAnimation *changeColor = [CABasicAnimation animationWithKeyPath:@"backgroundColor"];
changeColor.fromValue = (id)[UIColor greenColor].CGColor;
changeColor.toValue = (id)[UIColor blueColor].CGColor;
changeColor.duration = 1.0; // For convenience
[greenLayer addAnimation:changeColor forKey:@"Change color"];
greenLayer.speed = 0.0; // Pause the animation
CABasicAnimation *changePosition = [CABasicAnimation animationWithKeyPath:@"position"];
changePosition.fromValue = [NSValue valueWithCGPoint:CGPointMake(CGRectGetWidth([[self view] bounds]) / 2, CGRectGetHeight([[self view] bounds]) / 2)];
changePosition.toValue = [NSValue valueWithCGPoint:CGPointMake(CGRectGetWidth([[self view] bounds]), CGRectGetHeight([[self view] bounds]) / 2)];
changePosition.duration = 1.0;
[baseLayer addAnimation:changePosition forKey:@"Change position"];
baseLayer.speed = 0.0;
}
- (void)sliderValueChanged:(UISlider *)slider
{
[baseLayer setTimeOffset:[slider value]];
[greenLayer setTimeOffset:[slider value]];
}
我的问题:我是否需要单独更改每一层的 timeOffset
(这显然有效),或者我在这里遗漏了什么,我可以用更智能的解决方案?
(当然这是一个简单的例子,但我的实际层次结构可能更复杂一些,理论上可以有任意层数)
当您从子图层(在本例中为 greenLayer)中移除 speed = 0 时它应该可以工作。
速度属性相对于父层起作用,因此您可以通过调整父层的速度来暂停所有动画。子层上的速度将相对于父层速度起作用。
我有一段相当简单的示例代码,其中我有一个由三层组成的简单层次结构;
view layer
|- base layer
|- green layer
现在我想移动基础层,同时调整绿色层的颜色,所以我添加了一个滑块来控制动画。
代码如下所示:
@implementation ViewController
- (void)loadView
{
[super loadView];
baseLayer = [CALayer layer];
[baseLayer setFrame:[[self view] frame]];
[baseLayer setBackgroundColor:[[[UIColor redColor] colorWithAlphaComponent:0.5] CGColor]];
[[[self view] layer] addSublayer:baseLayer];
greenLayer = [CALayer layer];
[greenLayer setBounds:[baseLayer bounds]];
[greenLayer setBackgroundColor:[[UIColor greenColor] CGColor]];
[baseLayer addSublayer:greenLayer];
UISlider *slider = [[UISlider alloc] initWithFrame:CGRectMake(0, CGRectGetHeight([[self view] bounds]) - 44.0f, CGRectGetWidth([[self view] bounds]), 44.0f)];
[slider addTarget:self action:@selector(sliderValueChanged:) forControlEvents:UIControlEventValueChanged];
[[self view] addSubview:slider];
CABasicAnimation *changeColor = [CABasicAnimation animationWithKeyPath:@"backgroundColor"];
changeColor.fromValue = (id)[UIColor greenColor].CGColor;
changeColor.toValue = (id)[UIColor blueColor].CGColor;
changeColor.duration = 1.0; // For convenience
[greenLayer addAnimation:changeColor forKey:@"Change color"];
greenLayer.speed = 0.0; // Pause the animation
CABasicAnimation *changePosition = [CABasicAnimation animationWithKeyPath:@"position"];
changePosition.fromValue = [NSValue valueWithCGPoint:CGPointMake(CGRectGetWidth([[self view] bounds]) / 2, CGRectGetHeight([[self view] bounds]) / 2)];
changePosition.toValue = [NSValue valueWithCGPoint:CGPointMake(CGRectGetWidth([[self view] bounds]), CGRectGetHeight([[self view] bounds]) / 2)];
changePosition.duration = 1.0;
[baseLayer addAnimation:changePosition forKey:@"Change position"];
baseLayer.speed = 0.0;
}
- (void)sliderValueChanged:(UISlider *)slider
{
[baseLayer setTimeOffset:[slider value]];
[greenLayer setTimeOffset:[slider value]];
}
我的问题:我是否需要单独更改每一层的 timeOffset
(这显然有效),或者我在这里遗漏了什么,我可以用更智能的解决方案?
(当然这是一个简单的例子,但我的实际层次结构可能更复杂一些,理论上可以有任意层数)
当您从子图层(在本例中为 greenLayer)中移除 speed = 0 时它应该可以工作。
速度属性相对于父层起作用,因此您可以通过调整父层的速度来暂停所有动画。子层上的速度将相对于父层速度起作用。