在 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/