微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

添加从一个视图流向另一个视图的微光动画 更新

如何解决添加从一个视图流向另一个视图的微光动画 更新

我正在尝试创建从一个视图流向另一个视图的微光动画。以下是我到目前为止的代码

override func viewDidLoad() {
    super.viewDidLoad()
    view1.backgroundColor = .purple
    view2.backgroundColor = .purple
    view1.startAnimating()
    //let seconds = 2.0
    //dispatchQueue.main.asyncAfter(deadline: .Now() + seconds) {
        self.view2.startAnimating()
    //}
}

class ShimmerView: UIView {

let gradientColorOne : CGColor = UIColor.purple.cgColor
let gradientColorTwo : CGColor = UIColor.yellow.cgColor

func addGradientLayer() -> CAGradientLayer {
    
    let gradientLayer = CAGradientLayer()
    
    gradientLayer.frame = self.bounds
    gradientLayer.startPoint = CGPoint(x: 0.0,y: 0.0)
    gradientLayer.endPoint = CGPoint(x: 0.0,y: 1.0)
    gradientLayer.colors = [gradientColorOne,gradientColorTwo,gradientColorOne]
    gradientLayer.locations = [0.0,0.5,1.0]
    self.layer.addSublayer(gradientLayer)
    
    return gradientLayer
}

func addAnimation() -> CABasicAnimation {
   
    let animation = CABasicAnimation(keyPath: "locations")
    animation.fromValue = [-1.0,-0.5,0.0]
    animation.tovalue = [1.0,1.5,2.0]
    animation.repeatCount = .infinity
    animation.duration = 2
    return animation
}

func startAnimating() {
    
    let gradientLayer = addGradientLayer()
    let animation = addAnimation()
   
    gradientLayer.add(animation,forKey: animation.keyPath)
}
}

我尝试添加延迟,但我想这不会奏效,因为下次动画应该以进一步的延迟开始。

这就是它现在的行为方式。动画并行发生:

enter image description here

但是,我想要的是它从 view1 开始动画,然后在 view2 中完成并继续这样做。关于如何实现这一目标的任何想法/建议?谢谢。

解决方法

您可以尝试从呼叫站点控制动画顺序,如下所示。

  1. 像这样在 animationDuration 中定义一个名为 ShimmerView 的常量。
public static let animationDuration: Double = 2.0
  1. 像这样更新 addAnimation() 实现。
// Remove this line,We need this to be performed only once at a time.
/*
animation.repeatCount = .infinity
*/

// Update this line to use the constant defined earlier
animation.duration = ShimmerView.animationDuration
  1. 您现在可以从您的呼叫站点执行此操作。
class ViewController: UIViewController {
    
    let view1 = ShimmerView()
    let view2 = ShimmerView()

    func startAnimating() {
        view1.startAnimating()

        let interval = ShimmerView.animationDuration
        DispatchQueue.main.asyncAfter(deadline: .now() + interval) { [weak self] in
            self?.view2.startAnimating()

            DispatchQueue.main.asyncAfter(deadline: .now() + interval) { [weak self] in
                self?.startAnimating()
            }
        }
    }
}

更新

这种几乎可以,但是当view1完成动画并且view2启动它时,view1上的渐变位于中间,反之亦然。因此,它没有提供从上到下的清晰流畅的动画。

问题是您的代码没有在动画完成时从您的视图中删除 gradientLayer 实例。您可以使用 CATransaction.setCompletionBlock 完成,如下所示。

import Foundation
import UIKit

class ShimmerView: UIView {
    
    static let animationDuration: Double = 2.0
    let gradientColorOne: CGColor = UIColor.purple.cgColor
    let gradientColorTwo: CGColor = UIColor.yellow.cgColor
    
    lazy var gradientLayer: CAGradientLayer = {
        let gradient = CAGradientLayer()
        gradient.startPoint = CGPoint(x: 0.0,y: 0.0)
        gradient.endPoint = CGPoint(x: 0.0,y: 1.0)
        gradient.colors = [gradientColorOne,gradientColorTwo,gradientColorOne]
        gradient.locations = [0.0,0.5,1.0]
        return gradient
    }()
    
    func addGradientLayer() {
        gradientLayer.frame = self.bounds
        self.layer.addSublayer(gradientLayer)
    }
    
    func removeGradientLayer() {
        gradientLayer.removeFromSuperlayer()
    }

    func addAnimation() -> CABasicAnimation {
        let animation = CABasicAnimation(keyPath: "locations")
        animation.fromValue = [-1.0,-0.5,0.0]
        animation.toValue = [1.0,1.5,2.0]
        animation.duration = ShimmerView.animationDuration
        return animation
    }
    
    func startAnimating() {
        self.addGradientLayer()
        let animation = addAnimation()
        
        CATransaction.begin()
        // Setting this block before adding the animation is crucial
        CATransaction.setCompletionBlock({ [weak self] in
            self?.removeGradientLayer()
        })
        gradientLayer.add(animation,forKey: animation.keyPath)
        CATransaction.commit()
    }
    
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。