Objective-C-CABasicAnimation在动画之后应用更改吗?

Objective-C-CABasicAnimation在动画之后应用更改吗?

问题描述:

我正在使用CABasicAnimation移动和调整图像视图的大小.我希望将图像视图添加到超级视图中,进行动画处理,然后从超级视图中删除.

I am using CABasicAnimation to move and resize an image view. I want the image view to be added to the superview, animate, and then be removed from the superview.

为了实现这一点,我正在监听CAAnimationGroup的委托调用,并在调用它后立即从超级视图中删除图像视图.

In order to achieve that I am listening for delegate call of my CAAnimationGroup, and as soon as it gets called I remove the image view from the superview.

问题在于,有时图像在从超级视图中移除之前会在初始位置闪烁.避免这种行为的最佳方法是什么?

The problem is that sometimes the image blinks in the initial location before being removed from the superview. What's the best way to avoid this behavior?

CAAnimationGroup *animGroup = [CAAnimationGroup animation];
    animGroup.animations = [NSArray arrayWithObjects:moveAnim, scaleAnim, opacityAnim, nil];
    animGroup.duration = .5;
    animGroup.delegate = self;
    [imageView.layer addAnimation:animGroup forKey:nil];

将动画添加到图层时,该动画不会更改图层的属性.而是,系统创建该层的副本.原始层称为模型层,副本层称为表示层.表示层的属性随动画的进行而变化,但是模型层的属性保持不变.

When you add an animation to a layer, the animation does not change the layer's properties. Instead, the system creates a copy of the layer. The original layer is called the model layer, and the duplicate is called the presentation layer. The presentation layer's properties change as the animation progresses, but the model layer's properties stay unchanged.

当删除动画时,系统将破坏表示层,仅保留模型层,然后模型层的属性将控制如何绘制该层.因此,如果模型层的属性与表示层属性的最终动画值不匹配,则该层将立即重置为其在动画之前的外观.

When you remove the animation, the system destroys the presentation layer, leaving only the model layer, and the model layer's properties then control how the layer is drawn. So if the model layer's properties don't match the final animated values of the presentation layer's properties, the layer will instantly reset to its appearance before the animation.

要解决此问题,您需要将模型层的属性设置为动画的最终值,然后然后将动画添加到该层.您要按此顺序进行操作,因为更改图层属性可以为该属性添加一个隐式动画,这将与您要显式添加的动画发生冲突.您要确保显式动画覆盖隐式动画.

To fix this, you need to set the model layer's properties to the final values of the animation, and then add the animation to the layer. You want to do it in this order because changing a layer property can add an implicit animation for the property, which would conflict with the animation you want to explicitly add. You want to make sure your explicit animation overrides the implicit animation.

那么您如何做所有这一切?基本配方如下:

So how do you do all this? The basic recipe looks like this:

CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"position"];
animation.fromValue = [NSValue valueWithCGPoint:myLayer.position];
layer.position = newPosition; // HERE I UPDATE THE MODEL LAYER'S PROPERTY
animation.toValue = [NSValue valueWithCGPoint:myLayer.position];
animation.duration = .5;
[myLayer addAnimation:animation forKey:animation.keyPath];

我没有使用动画组,所以我不完全知道您可能需要更改什么.我只是将每个动画分别添加到图层中.

I haven't used an animation group so I don't know exactly what you might need to change. I just add each animation separately to the layer.

我还发现使用+[CATransaction setCompletionBlock:]方法为一个或多个动画设置完成处理程序要容易得多,而不是尝试使用动画的委托.设置交易的完成块,然后添加动画:

I also find it easier to use the +[CATransaction setCompletionBlock:] method to set a completion handler for one or several animations, instead of trying to use an animation's delegate. You set the transaction's completion block, then add the animations:

[CATransaction begin]; {
    [CATransaction setCompletionBlock:^{
        [self.imageView removeFromSuperview];
    }];
    [self addPositionAnimation];
    [self addScaleAnimation];
    [self addOpacityAnimation];
} [CATransaction commit];