我设法实现了这一点,并在 UIView 扩展中创建了一个函数:
@discardableResult public func addSlidingGradientLayer(withDuration duration: Double = 3.0, animationDelegate delegate: CAAnimationDelegate? = nil) -> CAGradientLayer {
let gradientLayer = CAGradientLayer()
gradientLayer.frame = bounds
gradientLayer.colors = [UIColor.white.cgColor, UIColor.clear.cgColor, UIColor.clear.cgColor]
gradientLayer.startPoint = CGPoint(x: -1.0, y: 0.5)
gradientLayer.endPoint = CGPoint(x: 1.0, y: 0.5)
let gradientAnimation = CABasicAnimation(keyPath: "startPoint")
gradientAnimation.fromValue = gradientLayer.startPoint
gradientAnimation.toValue = gradientLayer.endPoint
gradientAnimation.duration = duration
gradientAnimation.delegate = delegate
gradientLayer.add(gradientAnimation, forKey: "startPoint")
layer.mask = gradientLayer
return gradientLayer
}
首先,我们创建一个CAGradientLayer 实例,用作视图的掩码(在本例中为UILabel)。
然后我们创建一个CABasicAnimation 实例,我们用它来为CAGradientLayer 的startPoint 设置动画。这具有将 startPoint 从左向右滑动的效果,并提供了一些 duration 值。
最后,我们也是CABasicAnimation 的代表。那么,如果我们遵守CAAnimationDelegate协议,我们可以在动画完成后执行一些代码。
这是您可以使用此扩展程序的方式:
class ViewController: UIViewController {
@IBOutlet weak var someLabel: UILabel!
private func configureSomeLabel() {
someLabel.text = "Sliding into existence!"
someLabel.sizeToFit()
someLabel.addSlidingGradientLayer(withDuration: 3.0, animationDelegate: self)
}
override func viewDidLoad() {
super.viewDidLoad()
configureSomeLabel()
}
}
someLabel 已连接到您的故事板的位置。由于我们已将此视图控制器指定为动画委托,因此我们需要添加:
extension ViewController: CAAnimationDelegate {
func animationDidStop(_ anim: CAAnimation, finished flag: Bool) {
someLabel.layer.mask = nil
}
}
我选择移除遮罩层的位置。
希望这对某人有所帮助!