如何解决添加从一个视图流向另一个视图的微光动画 更新
我正在尝试创建从一个视图流向另一个视图的微光动画。以下是我到目前为止的代码:
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)
}
}
我尝试添加延迟,但我想这不会奏效,因为下次动画应该以进一步的延迟开始。
这就是它现在的行为方式。动画并行发生:
但是,我想要的是它从 view1 开始动画,然后在 view2 中完成并继续这样做。关于如何实现这一目标的任何想法/建议?谢谢。
解决方法
您可以尝试从呼叫站点控制动画顺序,如下所示。
- 像这样在
animationDuration
中定义一个名为ShimmerView
的常量。
public static let animationDuration: Double = 2.0
- 像这样更新
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
- 您现在可以从您的呼叫站点执行此操作。
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 举报,一经查实,本站将立刻删除。