2012-09-13 35 views
2

我有一个名为specialLayer的子图的视图。不透明度的隐式动画像这样被禁用:为什么我不能在CABasicAnimation完成后设置图层的不透明度?

self.specialLayer.actions = [NSDictionary dictionaryWithObjectsAndKeys: 
              [NSNull null], @"opacity", nil]; 

只有两种访问此子图层的方法。

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

出现这种情况:

1)用户按下一个按钮向下(控股)和-touchDown被调用。 specialLayer的不透明度立即变为0.25

2)用户释放按钮并调用-touchUp。 specialLayer的不透明动画回到1.0

此序列仅适用于一次!

3)用户再次按下按钮(保持)并调用-touchDown。但specialLayer的不透明度在屏幕上不会改变!即使self.specialLayer.opacity = 0.25f;被调用,也没有任何反应。不透明度似乎仍然是1.0f。

4)用户抬起手指,-touchUp被调用。 specialLayer的不透明度JUMPS为0.25,从那里动画到1.0f。

我用NSLog检查,以确保方法被调用的顺序。他们是这样。

当我取消注释动画代码并将不透明度直接设置为1.0时,后续直接不透明度更改立即生效。这绝对是导致问题的CABasicAnimation。删除禁用隐式动画的代码对此问题没有影响。

我不能为了我的生活弄清楚这里发生了什么。为什么CALayer不能反映我为不透明度添加CABasicAnimation后一段时间后为其设置的不透明度值?这是一个错误?

我在做什么错?

+0

你是什么意思层的不透明度被打破?您需要在添加动画之前设置图层不透明度的最终值。像layer.opacity = 1.0 – msk

+0

用更多细节更新了问题。 –

+0

@ProudMember:你看过我的回答吗?第一句话解释了你的根本问题。请让我知道,如果你有任何问题。 –

回答

8

您将动画的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]; 

这样做的原因是因为路层绘制的作品。当CoreAnimation将图层树渲染到屏幕上时,它会复制模型树并生成所谓的表示树。它通过复制所有图层,然后应用所有动画来完成。因此,它会覆盖图层上的每个动画,将时间插入定时函数,将结果插入到from/to值之间的插值中,并将该最终值应用回表示层的属性。

因此,当您永久在该图层上留下动画时,此动画将始终覆盖该键的实际模型值。无论您更改多少次layer.opacity,控制opacity的动画将始终会为演示目的而覆盖该值。

同样的原因也是为什么你可以在添加动画后将layer.opacity设置为任何你想要的,因为动画将优先。只有当动画被移除时(动画完成时默认发生)才会再次使用该属性的模型值。

+0

有一个类似的问题(它与动画和不透明度有关),我尝试在这里回答:http://stackoverflow.com/questions/12396160/why-do-some-animatable-properties-set-outside-an-动画 - 嵌段 - 未取效应/ 12397485#12397485。我很好奇答案。对不起,我不知道如何通过评论与你联系... – tiguero

相关问题