为什么在添加视图后立即启动UIView动画不起作用?

时间:2017-07-01 22:45:39

标签: ios swift uiview uiviewanimation catransaction

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
        )
    }
}

但是,结果是当视图在superview中可见时动画已经结束。 UIView.animate没有动画,但会立即设置self.layer.colors,可能是因为在调用didMoveToSuperview时视图尚未显示。

如何让动画正常启动?

1 个答案:

答案 0 :(得分:2)

使用核心动画制作渐变动画可以通过创建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秒动画,动画为垂直的红色到绿色渐变。