为什么在添加视图后立即启动时 UIView 动画不起作用?
Why is UIView animation not working when starting right after view is added?
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
时视图尚不可见。
怎样才能让动画正常启动?
可以通过创建 CABasicAnimation
并将其添加到您的 CAGradientLayer
来使用核心动画制作渐变动画。您不需要将其包装在 UIView
动画块中,您可以从 viewDidMoveToSuperview
执行此操作,前提是您在根视图具有后的某个时间将 UIView
子类实例添加到视图层次结构中已添加到 UIWindow
。例如,在操场上可以写:
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 秒动画。
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
时视图尚不可见。
怎样才能让动画正常启动?
可以通过创建 CABasicAnimation
并将其添加到您的 CAGradientLayer
来使用核心动画制作渐变动画。您不需要将其包装在 UIView
动画块中,您可以从 viewDidMoveToSuperview
执行此操作,前提是您在根视图具有后的某个时间将 UIView
子类实例添加到视图层次结构中已添加到 UIWindow
。例如,在操场上可以写:
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 秒动画。