Objective-C - 动画后应用更改的CABasicAnimation?

ary*_*axt 60 core-animation objective-c

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

为了实现这一点,我正在监听我的委托调用CAAnimationGroup,并且一旦调用它,我就从superview中删除图像视图.

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

CAAnimationGroup *animGroup = [CAAnimationGroup animation];
    animGroup.animations = [NSArray arrayWithObjects:moveAnim, scaleAnim, opacityAnim, nil];
    animGroup.duration = .5;
    animGroup.delegate = self;
    [imageView.layer addAnimation:animGroup forKey:nil];
Run Code Online (Sandbox Code Playgroud)

rob*_*off 186

向图层添加动画时,动画不会更改图层的属性.相反,系统会创建图层的副本.原始层称为模型层,副本称为表示层.表示层的属性随着动画的进展而变化,但模型层的属性保持不变.

删除动画时,系统会破坏表示层,只留下模型图层,然后模型图层的属性控制图层的绘制方式.因此,如果模型图层的属性与表示层属性的最终动画值不匹配,则图层将立即重置为动画前的外观.

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

那么你怎么做这一切?基本配方如下:

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];
Run Code Online (Sandbox Code Playgroud)

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

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

[CATransaction begin]; {
    [CATransaction setCompletionBlock:^{
        [self.imageView removeFromSuperview];
    }];
    [self addPositionAnimation];
    [self addScaleAnimation];
    [self addOpacityAnimation];
} [CATransaction commit];
Run Code Online (Sandbox Code Playgroud)

  • 除了模型层在调用完成块之前短暂出现之外,这几乎*完美地工作.有什么办法可以避免吗? (3认同)

Lil*_*ard 33

完成后会自动删除CAAnimations.有一个属性removedOnCompletion可以控制它.你应该把它设置为NO.

另外,有一些已知的东西fillMode控制动画在其持续时间之前和之后的行为.这是一个声明的属性CAMediaTiming(CAAnimation符合).你应该把它设置为kCAFillModeForwards.

通过这两个更改,动画应在完成后保留.但是,我不知道您是否需要在组中更改这些内容,或者在组内的单个动画中更改这些内容,或者两者都知道.

  • 这实际上是持久化动画并强制它保留在内存中的错误方法.最好的方法是创建动画,将其添加到图层,然后将您在图层上设置动画的属性设置为最终值.动画将覆盖动画持续时间的最终值以及完成时的最终值您将看到最终状态的图层.不需要任何fillMode怪异. (6认同)
  • 这只是保持表示层可见.在动画按钮的情况下,您将无法通过这种方式在动画后与按钮交互. (4认同)