CAGradientLayer属性不在UIView动画块中设置动画 [英] CAGradientLayer properties not animating within UIView animation block

查看:141
本文介绍了CAGradientLayer属性不在UIView动画块中设置动画的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a feeling I'm overlooking something elementary, but what better way to find it than to be wrong on the internet?

我有一个相当基本的用户界面。我的 UIViewController 的视图是一个子类,其 + layerClass CAGradientLayer 。根据用户的操作,我需要移动一些UI元素,并更改背景渐变的值。代码如下所示:

I have a fairly basic UI. The view for my UIViewController is a subclass whose +layerClass is CAGradientLayer. Depending on the user's actions, I need to move some UI elements around, and change the values of the background's gradient. The code looks something like this:

[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 issue is that the changes I make in this block to the subviews animate just fine (stuff moves and fades), but the change to the gradient's colors does not. It just swaps.

现在,文档确实说动画块中的Core Animation代码不会继承块的属性(持续时间,放松等)。但是,根本没有定义动画交易吗? (文档的含义似乎是你会得到一个默认动画,我得不到。)

Now, the documentation does say that Core Animation code within an animation block won't inherit the block's properties (duration, easing, etc.). But is it the case that that doesn't define an animation transaction at all? (The implication of the docs seems to be that you'll get a default animation, where I get none.)

到使用显式 CAAnimation 来使其工作? (如果是这样,为什么?)

Do I have to use explicit CAAnimation to make this work? (And if so, why?)

推荐答案

这里似乎有两件事情。第一个(正如Travis正确指出的那样,文档说明)是UIKit动画似乎对应用于 CALayer 属性更改的隐式动画没有任何影响。我认为这很奇怪(UIKit 必须使用Core Animation),但它就是它。

There seem to be two things going on here. The first (as Travis correctly points out, and the documentation states) is that UIKit animations don't seem to hold any sway over the implicit animation applied to CALayer property changes. I think this is weird (UIKit must be using Core Animation), but it is what it is.

这是一个(可能非常愚蠢? )该问题的解决方法:

Here's a (possibly very dumb?) workaround for that problem:

  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动画列表中。)

The other key is that this gradient layer is my view's layer. That means that my view is the layer's delegate (where, if the gradient layer was just a sublayer, it wouldn't have a delegate). And the UIView implementation of -actionForLayer:forKey: returns NSNull for the "colors" event. (Probably every event that isn't on a specific list of UIView animations.)

将以下代码添加到我的视图中将导致颜色更改按预期动画:

Adding the following code to my view will cause the color change to be animated as expected:

- (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;
}

这篇关于CAGradientLayer属性不在UIView动画块中设置动画的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆