将 CALayer 更改应用到 UIView

Posted

技术标签:

【中文标题】将 CALayer 更改应用到 UIView【英文标题】:Apply CALayer changes to UIView 【发布时间】:2014-07-24 12:58:29 【问题描述】:

我有一个 UIView。我将动画应用到它的 CALayer。

[view.layer addAnimation:groupAnimation forKey:name];

我希望图层的最终状态是动画后 UIView 的状态。假设我旋转了 45 度并使用图层移动到新位置;动画后我的视图是否可能处于该状态?因为现在,在动画之后,它又回到了 UIView 的原始状态。我希望能在这方面得到一些帮助。谢谢。

【问题讨论】:

【参考方案1】:

要理解的是图层动画只是动画;它只是一种临时覆盖屏幕的“电影”。当动画结束时,“电影”被移除,从而揭示了真实情况。由你决定将这种情况与电影的最后一帧相匹配。

UIView 动画在很大程度上为您做到了这一点。但是图层动画完全取决于您。

因此,假设您为位置变化设置动画;做某事以使图层或视图实际上是您动画的位置完全取决于您。

通常的做法是将更改作为一组单独的命令自己执行。但请注意不要做任何可能触发隐式层动画的事情,因为这会与您尝试显式执行的动画冲突。

这是示例代码(与您的无关,但它确实显示了一般形式):

CAAnimationGroup* group = // ...
// ... configure the animation ...
[view.layer addAnimation:group forKey:nil];
// now we are ready to set up the view to look like the final "frame" of the animation
[CATransaction setDisableActions:YES]; // do not trigger implicit animation by mistake
view.layer.position = finalPosition; // assume we have worked this out

【讨论】:

从这里开始查看我关于这个主题的完整教程:apeth.com/iosBook/ch17.html#_using_a_cabasicanimation【参考方案2】:

在为 CALayer 设置动画或使用 CAAnimationGroup 时,必须设置以下属性,例如:

groupAnimation.removedOnCompletion = NO;
groupAnimation.fillMode = kCAFillModeForwards;

另见:After Animation, View position resets


还请注意,将动画直接应用于视图本身可能会有所帮助,而不是通过访问视图的图层。这是使用动画块完成的,我发现它非常有用。

可以通过多种方式自定义块样式动画,但这里有一个基本示例,当您的视图需要动画时,可以在函数中调用它:

- (void) animateMyView

    CGRect newViewFrame = CGRectMake(x,y,w,h);
    [UIView animateWithDuration:0.5
                          delay:0
                        options: (UIViewAnimationOptionCurveLinear )
                     animations:^
                         self.myView = CGAffineTransformMakeRotation (45);
                         [self.myView setBounds:newViewFrame];
                    
                     completion:NULL];

如需了解更多信息,请参阅Apple's documentation on View Animation。

【讨论】:

我的自动布局被禁用,但动画结束后,它又回到了原来的状态。实际上,我尝试做 UIViewAnimation 但我无法实现我想要的。 CALayer 动画更加灵活。有没有办法确保我的 UIView 与我动画的图层处于相同的状态? 答案已更新以包含以下信息:为 CALayer 设置动画或使用 CAAnimationGroup 时,必须设置以下属性: groupAnimation.removedOnCompletion = NO; groupAnimation.fillMode = kCAFillModeForwards;另见:***.com/questions/226555/… 以这种方式滥用removedOnCompletion是绝对错误的做法,不应作为建议提供 @matt,什么时候使用removedOnCompletionfillMode 是正确的做法?不能使用表示树中的图层,而不是保持最后一个动画帧和实际图层之间的奇偶性? fillMode 是关于组内不同时间开始/结束的不同动画之间的关系。 removedOnCompletion 几乎不需要。

以上是关于将 CALayer 更改应用到 UIView的主要内容,如果未能解决你的问题,请参考以下文章

禁用 CALayer 蒙版帧更改动画

播放视频时的 CALayer 消息(Xcode 12.5.1,Swift 5)

滚动视图滚动时,有任何更好的方法可以无延迟地更改CAlayer位置

当 UIViewController 显示弹出框时,更改 CALayer 颜色与 UIView tintColor 同步

在 CALayer 上应用两个以上 CIFilter

在 NSView 边界更改中托管的 CALayer