为什么在向图层添加子图层时会隐藏隐式动画?

时间:2013-03-19 19:54:11

标签: ios core-animation

在UIView子类中,我有这个方法:

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    UITouch * aTouch = [touches anyObject];
    CGPoint loc = [aTouch locationInView:self];

    CALayer * layer = [CALayer layer];
    [layer setBackgroundColor: [[UIColor colorWithHue:(float)rand()/RAND_MAX saturation:1 brightness:1 alpha:1] CGColor]];
    [layer setFrame:CGRectMake(0, 0, 64, 64)];
    [layer setCornerRadius:7];
    [layer setPosition:loc];

    [layer setOpacity:0];

    [self.layer addSublayer:layer];


    CABasicAnimation * opacityAnim = [CABasicAnimation animationWithKeyPath:@"opacity"];
    opacityAnim.duration=2.42;
    opacityAnim.fromValue=[NSNumber numberWithFloat:0];
    opacityAnim.toValue=  [NSNumber numberWithFloat:1];
    opacityAnim.fillMode = kCAFillModeForwards;
    opacityAnim.timingFunction= [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
    opacityAnim.removedOnCompletion=NO;
    opacityAnim.delegate=self;

//  explicit animation is working as expected
//  [layer addAnimation:opacityAnim forKey:@"opacityAnimation"];

//     Why isn't the implicit animation working ?
[layer setOpacity:1];
}

我错过了什么?我希望CALayer layer的不透明度可以使用此方法中的最后一行进行隐式动画处理。

我的解决方案

由于Duncan的回答,我在这里解决了这个问题。

-(CALayer *) layerFactory:(CGPoint) loc {
    CALayer * layer = [CALayer layer];
    [layer setBackgroundColor: [[UIColor colorWithHue:(float)rand()/RAND_MAX saturation:1 brightness:1 alpha:1] CGColor]];
    [layer setFrame:CGRectMake(0, 0, 64, 64)];
    [layer setCornerRadius:7];
    [layer setPosition:loc];
    [layer setOpacity:0];
    return layer;
}

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {

    UITouch * aTouch = [touches anyObject];
    CGPoint loc = [aTouch locationInView:self];


    [CATransaction begin];
    CALayer * layer = [self layerFactory:loc];
    [self.layer addSublayer:layer];
    [CATransaction commit];


    [CATransaction begin];
    [CATransaction setAnimationDuration:0.45];
    [layer setOpacity:1];
    [CATransaction commit];

}

您只需要创建图层,并在两个不同的CATransaction块中修改不透明度。但是,将图层的创建(而不是添加)移动到layerFactory方法不会改变任何情况。

我不知道这是否是最佳解决方案,但它正在发挥作用。

1 个答案:

答案 0 :(得分:4)

您无法创建图层并设置其不透明度,然后在同一方法中将不透明度设置为新值并获取隐式动画。尝试将您的创建/配置层代码放在CATransaction开始/结束块中,然后将代码设置为在另一个事务开始/结束块内设置不透明度。

我认为这样可行,但必须尝试才能确定。

如果这不起作用,请调用代码,使用performSelector:withObject:afterDelay并将延迟值设置为0,将不透明度设置为1.这将让系统添加不透明度为0的图层,然后处理更改不透明度为1作为单独的交易。