Pro*_*ber 2 iphone core-animation calayer ipad ios
我有一个名为sublayer的视图specialLayer.不透明度的隐式动画被禁用,如下所示:
self.specialLayer.actions = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNull null], @"opacity", nil];
Run Code Online (Sandbox Code Playgroud)
访问此子图层的方法只有两种.
- (void)touchDown {
self.specialLayer.opacity = 0.25f;
}
- (void)touchUp {
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"opacity"];
animation.fromValue = [NSNumber numberWithFloat:self.specialLayer.opacity];
animation.toValue = [NSNumber numberWithFloat:1.0];
animation.duration = 0.5;
animation.removedOnCompletion = NO;
animation.fillMode = kCAFillModeForwards;
animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
[self.specialLayer addAnimation:animation forKey:@"opacity"];
}
Run Code Online (Sandbox Code Playgroud)
有时候是这样的:
1)用户按下按钮(保持)并调用-touchDown.specialLayer的不透明度立即变为0.25
2)用户释放按钮和-touchUp被调用.specialLayer的不透明度可以恢复为1.0
此序列仅适用于ONCE!
3)用户再次按下按钮(按住)并调用-touchDown.但specialLayer的不透明度在屏幕上不会改变!即使self.specialLayer.opacity = 0.25f;被召唤也没有任何事情发生.不透明度似乎仍为1.0f.
4)用户抬起手指并调用-touchUp.specialLayer的不透明度为0.25,从那里动画到1.0f.
我检查了NSLog以确保按此顺序调用方法.他们是这样.
当我取消注释动画代码并将不透明度直接设置为1.0时,后续的直接不透明度更改立即生效.绝对是导致问题的CABasicAnimation.删除禁用隐式动画的代码对此问题没有影响.
我不能为我的生活弄清楚这里发生了什么.为什么在我为不透明度添加CABasicAnimation之后的一段时间后,CALayer没有反映我设置的不透明度值?这是一个错误吗?
我究竟做错了什么?
您将动画设置removedOnCompletion为NO.这意味着当动画完成时,它仍然停留在图层上并仍然控制opacity渲染的值.当您再次调用此代码时,新动画将替换旧动画,从而导致跳转(因为它现在使用新设置0.25f作为起点).
解决的办法是只停留设置removedOnCompletion到NO.相反,您应该在添加动画的同时,将图层的实际不透明度设置为与动画端点相同的值.
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"opacity"];
// you can omit fromValue since you're setting it to the layer's opacity
// by omitting fromValue, it uses the current value instead. Just remember
// to not change layer.opacity until after you add the animation to the layer
animation.toValue = [NSNumber numberWithFloat:1];
animation.duration = 0.5;
animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
[layer addAnimation:animation forKey:@"opacity"];
layer.opacity = 1; // or layer.opacity = [animation.toValue floatValue];
Run Code Online (Sandbox Code Playgroud)
这是因为图层渲染的工作方式.当CoreAnimation将图层树渲染到屏幕时,它会复制模型树并生成所谓的表示树.它通过复制所有图层,然后应用所有动画来完成此操作.因此,它会遍历图层上的每个动画,将时间插入计时功能,将生成的进度插入到from/to值之间的插值中,并将该最终值应用回表示层的属性.
因此,当您永久地在图层上留下动画时,此动画将始终覆盖该键的实际模型值.更改次数无关紧要layer.opacity,控制的动画opacity将始终覆盖该值以用于演示目的.
同样的原因也是为什么你可以layer.opacity在添加动画后设置你想要的任何东西,因为动画将优先.仅当移除动画时(默认情况下在动画完成时才会发生),将再次使用该属性的模型值.
| 归档时间: |
|
| 查看次数: |
3041 次 |
| 最近记录: |