【问题标题】:Prevent CAGradientLayer locations from returning to original values after using CABasicAnimation使用 CABasicAnimation 后防止 CAGradientLayer 位置返回原始值
【发布时间】:2017-12-27 20:02:14
【问题描述】:

我正在尝试制作渐变动画,以便两种颜色的位置从左向右移动。问题是,一旦动画完成,渐变位置会迅速回到原来的位置。

这是我的游乐场代码:

import UIKit
import PlaygroundSupport

class MyViewController : UIViewController {

  let gradientLayer: CAGradientLayer = {
    let layer = CAGradientLayer()
    layer.colors = [ UIColor.red.cgColor, UIColor.blue.cgColor ]
    layer.locations = [0.0, 0.5]
    layer.startPoint = CGPoint(x: 0.0, y: 1.0)
    layer.endPoint = CGPoint(x: 1.0, y: 1.0)

    return layer
  }()

  override func viewDidLoad() {
    super.viewDidLoad()

    view.layer.addSublayer(gradientLayer)
    gradientLayer.frame = view.bounds

    let gradientChangeAnimation = CABasicAnimation(keyPath: "locations")
    gradientChangeAnimation.duration = 1
    gradientChangeAnimation.toValue = [0.5, 1.0]
    gradientLayer.add(gradientChangeAnimation, forKey: nil)

  }

  override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    gradientLayer.frame = view.frame
  }
}

// Present the view controller in the Live View window
PlaygroundPage.current.liveView = MyViewController()

如何防止动画完成后位置重置?

【问题讨论】:

    标签: ios swift core-animation cabasicanimation cagradientlayer


    【解决方案1】:

    您可以告诉它在完成时不要删除并将位置设置为新值:

    override func viewDidLoad() {
        super.viewDidLoad()
    
        view.layer.addSublayer(gradientLayer)
        gradientLayer.frame = view.bounds
    
        CATransaction.begin()
        CATransaction. setCompletionBlock {
            gradientLayer.locations = [0.5, 1.0]
            gradientLayer.removeAllAnimations()
        }
    
        let gradientChangeAnimation = CABasicAnimation(keyPath: "locations")
        gradientChangeAnimation.duration = 1
        gradientChangeAnimation.toValue = [0.5, 1.0]
        gradientLayer.add(gradientChangeAnimation, forKey: nil)
    
        CATransaction.commit()
    }
    

    或适当地设置 fillMode 和 isRemovedOnCompletion 属性。

    override func viewDidLoad() {
        super.viewDidLoad()
    
        view.layer.addSublayer(gradientLayer)
        gradientLayer.frame = view.bounds
    
        let gradientChangeAnimation = CABasicAnimation(keyPath: "locations")
        gradientChangeAnimation.duration = 1
        gradientChangeAnimation.toValue = [0.5, 1.0]
        gradientChangeAnimation.fillMode = kCAFillModeForwards
        gradientChangeAnimation.isRemovedOnCompletion = false
        gradientLayer.add(gradientChangeAnimation, forKey: nil)
    }
    

    【讨论】:

    • 就我个人而言,我喜欢最后一个解决方案,因为它有一个完成块。但这是所有偏好和需求。自己决定哪个最适合你..
    • 我已经尝试了第一个解决方案,但它不起作用。我将尝试其他两种解决方案。敬请期待……
    • 最后一个解决方案是唯一可行的。我会继续将其标记为正确。谢谢!
    • @DJSK;奇怪..其他解决方案过去对我有用(在我当前的一些项目中仍然有效),因此我添加了它们。好吧,至少现在我知道最后一个总是适用于每个案例/项目。
    • 是的,我也不知道为什么。很奇怪。
    猜你喜欢
    • 2011-12-02
    • 1970-01-01
    • 2023-04-02
    • 2021-08-29
    • 1970-01-01
    • 2019-04-06
    • 1970-01-01
    • 2013-03-22
    • 2015-12-01
    相关资源
    最近更新 更多