为啥在添加视图后立即启动 UIView 动画不起作用?
Posted
技术标签:
【中文标题】为啥在添加视图后立即启动 UIView 动画不起作用?【英文标题】:Why is UIView animation not working when starting right after view is added?为什么在添加视图后立即启动 UIView 动画不起作用? 【发布时间】:2017-07-01 22:45:39 【问题描述】:UIView
的动画应该在视图添加到父视图后立即开始:
class myView: UIView
override func didMoveToSuperview()
super.didMoveToSuperview()
UIView.animate(
withDuration: duration,
delay: 0,
options: .curveLinear,
animations:
CATransaction.begin()
CATransaction.setAnimationDuration(duration)
self.layer.colors = [color1, color2]
CATransaction.commit()
,
completion: nil
)
但是,结果是当视图在父视图中可见时动画已经结束。 UIView.animate
没有动画,而是立即设置self.layer.colors
,可能是因为调用didMoveToSuperview
时视图还不可见。
如何让动画正常启动?
【问题讨论】:
在视图控制器的生命周期中,您的MyView
实例添加到视图层次结构中的哪个位置?
@thefredelement 覆盖两个绘图函数都没有帮助,结果相同。
@beyowulf 在super.viewDidAppear(animated)
之后。
您是否要为CAGradientLayer
制作动画?
@beyowulf 是的..
【参考方案1】:
可以通过创建CABasicAnimation
并将其添加到您的CAGradientLayer
来使用核心动画制作渐变动画。您不需要将其包装在 UIView
动画块中,并且可以从 viewDidMoveToSuperview
执行此操作,前提是您在将根视图添加到 @987654326 之后的某个时间将 UIView
子类实例添加到视图层次结构中@。例如,在操场上可以写:
import UIKit
import PlaygroundSupport
class MyView: UIView
var duration = 20.0
var fromColors = [UIColor.orange.cgColor, UIColor.blue.cgColor]
var toColors = [UIColor.red.cgColor, UIColor.green.cgColor]
override func didMoveToSuperview()
super.didMoveToSuperview()
let gradientLayer = CAGradientLayer()
gradientLayer.frame = bounds
layer.addSublayer(gradientLayer)
let animation = CABasicAnimation(keyPath: "colors")
animation.fromValue = fromColors
animation.toValue = toColors
animation.duration = duration
gradientLayer.add(animation, forKey: nil)
gradientLayer.colors = toColors
class ViewController: UIViewController
override func viewDidAppear(_ animated: Bool)
super.viewDidAppear(animated)
let myView = MyView(frame: view.bounds)
view.addSubview(myView)
PlaygroundPage.current.liveView = ViewController()
并看到一个 20 秒的动画,从垂直的橙色到蓝色渐变动画到垂直的红色到绿色渐变。
【讨论】:
谢谢,现在可以正常使用了。唯一需要改变的是在添加动画gradientLayer.add(animation, forKey: nil)
之前应该设置最终状态gradientLayer.colors = toColors
。否则在做连续动画时有时会闪烁。甚至不再需要在didMoveToSuperview
中启动动画,它也可以在init
函数中使用。以上是关于为啥在添加视图后立即启动 UIView 动画不起作用?的主要内容,如果未能解决你的问题,请参考以下文章