我有一种感觉,我忽略了一些基本的东西,但是更好的方式找到它,而不是在互联网上出错?
我有一个相当基本的UI.我的UIViewController视图是一个子类,它的layerClass是CAGradientLayer.根据用户的操作,我需要移动一些UI元素,并更改背景渐变的值.代码看起来像这样:
[UIView animateWithDuration:0.3 animations:^{ self.subview1.frame = CGRectMake(...); self.subview2.frame = CGRectMake(...); self.subview2.alpha = 0; NSArray* newColors = [NSArray arrayWithObjects: (id)firstColor.CGColor,(id)secondColor.CGColor,nil]; [(CAGradientLayer *)self.layer setColors:newColors]; }];
问题是,我在这个块中对子视图的更改动画很好(东西移动和淡化),但是渐变颜色的改变并不是这样.它只是互换.
现在,the documentation does say核心动画代码在动画块内将不会继承该块的属性(持续时间,宽松等).但是,是不是完全没有定义一个动画交易? (文档的含义似乎是你会得到一个默认的动画,在那里我没有.)
我必须使用显式CAAnimation来使这项工作吗? (如果是,为什么?)
解决方法
这里似乎有两件事情.第一个(如Travis正确指出的,文档的状态)是UIKit动画似乎并不适用于应用于CALayer属性更改的隐式动画.我认为这是奇怪的(UIKit必须使用核心动画),但它是什么.
这是一个(可能非常愚蠢的)解决方法的问题:
NSTimeInterval duration = 2.0; // slow things down for ease of debugging [UIView animateWithDuration:duration animations:^{ [CATransaction begin]; [CATransaction setAnimationDuration:duration]; // ... do stuff to things here ... [CATransaction commit]; }];
另一个关键是这个梯度层是我视图的层.这意味着我的观点是层的委托(其中,如果梯度层只是一个子层,则不会有代理).而UIView实现的-actionForLayer:forKey:返回NSNull的“colors”事件. (可能是每个不在UIView动画的特定列表上的事件)
- (id<CAAction>)actionForLayer:(CALayer *)layer forKey:(NSString *)event { id<CAAction> action = [super actionForLayer:layer forKey:event]; if( [@"colors" isEqualToString:event] && (nil == action || (id)[NSNull null] == action) ) { action = [CABasicAnimation animationWithKeyPath:event]; } return action; }