ios - 为什么在向图层添加子图层时缺少隐式动画?

标签 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 的不透明度在此方法的最后一行隐式设置动画。

我的解决方案

由于邓肯的回答,这是我解决问题的方法。

-(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 block 中。但是,将层的创建(而不是添加)移动到 layerFactory 方法不会改变这种情况。

我不知道这是否是最佳解决方案,但它确实有效。

最佳答案

您不能创建一个层并设置它的不透明度,然后用相同的方法将不透明度设置为新值并获得隐式动画。尝试将创建/配置层代码放在 CATransaction 开始/结束 block 中,然后将不透明度设置为 1 的代码放在另一个事务开始/结束 block 中。

我认为这会奏效,但必须尝试才能确定。

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

关于ios - 为什么在向图层添加子图层时缺少隐式动画?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15509172/

相关文章:

ios - 从多部分 UITableView 中的自定义静态单元格检索标签文本

objective-c - 当一个 Action 已经在进行时,用一个按钮开始一个 Action

cocoa - 当主机窗口透明时应用 CIFilter 背景过滤器

iphone - 核心动画在哪里定义的?

iphone - 垂直对齐 CATextLayer 中的文本?

iphone - Flurry Analytics似乎没有在iOS 4.2中记录事件

ios - iPhone应用程序还必须在iPad上运行且未经修改,且必须为iPhone分辨率和2X iPhone 3GS分辨率

ios - 可以检索用于创建 SKPhysicsBody 对象的参数吗?

ios - 快速 fatal error 中的自定义 CollectionViewCell

ios - 在 iOS 中使用 Core 动画打开纸张动画