在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方法不会改变任何情况。
我不知道这是否是最佳解决方案,但它正在发挥作用。
答案 0 :(得分:4)
您无法创建图层并设置其不透明度,然后在同一方法中将不透明度设置为新值并获取隐式动画。尝试将您的创建/配置层代码放在CATransaction开始/结束块中,然后将代码设置为在另一个事务开始/结束块内设置不透明度。
我认为这样可行,但必须尝试才能确定。
如果这不起作用,请调用代码,使用performSelector:withObject:afterDelay并将延迟值设置为0,将不透明度设置为1.这将让系统添加不透明度为0的图层,然后处理更改不透明度为1作为单独的交易。