ios – CAGradientLayer属性不能在UIView动画块内动画

我有一种感觉,我忽略了一些基本的东西,但是更好的方式找到它,而不是在互联网上出错?

我有一个相当基本的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;
}

相关文章

当我们远离最新的 iOS 16 更新版本时,我们听到了困扰 Apple...
欧版/美版 特别说一下,美版选错了 可能会永久丧失4G,不过只...
一般在接外包的时候, 通常第三方需要安装你的app进行测...
前言为了让更多的人永远记住12月13日,各大厂都在这一天将应...