在插入的CAGradientLayer作为子层时,动画不工作。

问题描述 投票:0回答:1

我想在viewController加载时执行动画(全视图高度为88px高度,底部到顶部动画)。所以我在故事板上添加了一个UIView(animationView),在viewDidLoad()中添加了渐变,在viewDidAppear()中执行了如下动画。

override func viewDidLoad() {
        super.viewDidLoad()
        self.animationView.applyGradient(with: [UIColor(red: 0, green: 91/255, blue: 200/255, alpha: 1), UIColor(red: 0, green: 131/255, blue: 232/255, alpha: 1)])
}

override func viewDidAppear(_ animated: Bool) {

        super.viewDidAppear(animated)

        //Perform animation
        self.animationVWBottomContraint.constant = self.view.bounds.height - 88.0

        UIView.animate(withDuration: 0.75,delay: 10, options: .curveEaseIn, animations: {
            self.view.layoutIfNeeded()
        }, completion: {(_) in
            DispatchQueue.main.asyncAfter(deadline: .now()+6) {
                self.animationView.isHidden = true
            }
        }
extension UIView {

 open func applyGradient(with colours: [UIColor]) {

        //Create a gradient and apply it to the sublayer.
        let gradient = CAGradientLayer()
        gradient.frame = self.bounds
        gradient.name  = "grad1"
        gradient.colors = colours.map { $0.cgColor }
        gradient.startPoint = CGPoint(x: 0.0,y: 0.0)
        gradient.endPoint = CGPoint(x: 0.0,y: 1.0)
        self.layer.insertSublayer(gradient, at: 0)
    }
}

如果我们添加一张图片作为animationView的子视图来检查动画是否有效果,那么我们可以看到动画发生了。但是CAGradient层没有任何效果。

如果我们添加backgroundColor而不是gradient,动画就会如期发生。

override func viewDidLoad() {
        super.viewDidLoad()
        //self.animationView.applyGradient(with: [UIColor(red: 0, green: 91/255, blue: 200/255, alpha: 1), UIColor(red: 0, green: 131/255, blue: 232/255, alpha: 1)])
      self.animationView.backgroundColor = UIColor.blue
}

这意味着新添加的子层在layoutIfNeeded()时不会被调整大小。因此,我尝试过强制调用布局或创建子类,并将gradient作为自定义init的一部分。

self.animationView.layer.setNeedsLayout()
or 
self.animationView.layoutIfNeeded()
or
class GradientView : UIView {
    required init?(coder: NSCoder) {
        super.init(coder:coder)
        self.customInit()
    }
    override init(frame: CGRect) {
        super.init(frame: frame)
        self.customInit()
    }

    func animate(){
        UIView.animate(withDuration: 0.25, delay: 2, options: .curveLinear, animations: {
            self.frame.size.height = 80.0
            self.layoutIfNeeded()
        }, completion: nil)
    }

    func customInit(){

        let containerView = UIView()
        self.addSubview(containerView)
        containerView.frame = self.bounds
        self.autoresizingMask = [.flexibleHeight, .flexibleWidth]
        let gradient = CAGradientLayer()
               gradient.frame = self.bounds
               gradient.name  = "grad1"
               gradient.colors = [UIColor(red: 0, green: 91/255, blue: 200/255, alpha: 1), UIColor(red: 0, green: 131/255, blue: 232/255, alpha: 1)].map { $0.cgColor }
               gradient.startPoint = CGPoint(x: 0.0,y: 0.0)
               gradient.endPoint = CGPoint(x: 0.0,y: 1.0)
        containerView.layer.insertSublayer(gradient, at: 0)
    }
}

但是没有任何帮助。

我怎样才能解决这个问题?

先谢谢你。

ios swift animation cagradientlayer
1个回答
0
投票

这意味着新添加的子层在layoutIfNeeded()时不会被调整大小。

当父视图的边界框架发生变化时,图层不会自动调整自己的大小,例如:如果你应用阴影或边框到视图,然后改变视图的边界阴影不会自动更新。你必须在 layoutSubviews 所以把你的代码改为

class GradientView : UIView {
    private var gradient: CAGradientLayer?

    override func layoutSubviews() {
        super.layoutSubviews()
        self.gradient?.frame = self.bounds
    }

    required init?(coder: NSCoder) {
        super.init(coder:coder)
        self.customInit()
    }
    override init(frame: CGRect) {
        super.init(frame: frame)
        self.customInit()
    }

    func animate(){
        UIView.animate(withDuration: 0.25, delay: 2, options: .curveLinear, animations: {
            self.frame.size.height = 80.0
            self.layoutIfNeeded()
        }, completion: nil)
    }

    func customInit(){
        let containerView = UIView()
        self.addSubview(containerView)
        containerView.frame = self.bounds
        self.autoresizingMask = [.flexibleHeight, .flexibleWidth]
        self.gradient = CAGradientLayer()
        gradient?.frame = self.bounds
        gradient?.name  = "grad1"
        gradient?.colors = [UIColor(red: 0, green: 91/255, blue: 200/255, alpha: 1), UIColor(red: 0, green: 131/255, blue: 232/255, alpha: 1)].map { $0.cgColor }
        gradient?.startPoint = CGPoint(x: 0.0,y: 0.0)
        gradient?.endPoint = CGPoint(x: 0.0,y: 1.0)
        if let gradient = self.gradient {
            containerView.layer.insertSublayer(gradient, at: 0)
        }
    }
}

希望能帮到你

© www.soinside.com 2019 - 2024. All rights reserved.