Swift - 使用 animateWithDuration 淡化 CAGradientLayer

Posted

技术标签:

【中文标题】Swift - 使用 animateWithDuration 淡化 CAGradientLayer【英文标题】:Swift - Using animateWithDuration to fade CAGradientLayer 【发布时间】:2016-03-28 21:03:21 【问题描述】:

我有 switch 语句来控制我的背景渐变。它工作得很好(渐变变化),但是它突然改变了。我希望这些渐变以 0.25 的持续时间相互淡入。我的代码尝试如下。

控制背景的开关语句:

switch backgroundInput
case 50...69:
self.view.configureGradient([gradientColor1, gradientColor2])
case 70...90:
self.view.configureGradient([gradientColor2, gradientColor3])
case 91...110:
self.view.configureGradient([gradientColor3, gradientColor4])
case 111...130:
self.view.configureGradient([gradientColor4, gradientColor5])
case 131...150:
self.view.configureGradient([gradientColor5, gradientColor6])
case 151...170:
self.view.configureGradient([gradientColor6, gradientColor7])
default:
self.view.configureGradient([lightPurple, lightBlue])

控制渐变的扩展 这是我尝试动画持续时间的地方

extension UIView 
private func prepareGradient() -> CAGradientLayer 
    let gradientLayer = CAGradientLayer()
    gradientLayer.frame = self.bounds
    gradientLayer.startPoint = CGPoint(x: 0.0, y: 0.0)
    gradientLayer.endPoint = CGPoint(x: 1.0, y: 1.0)
    gradientLayer.zPosition = -1
    self.layer.addSublayer(gradientLayer)
    return gradientLayer

func configureGradient(colors:[CGColor]) 
    let gradientLayer = prepareGradient()
    UIView.animateWithDuration(0.25, delay: 0.0, options: UIViewAnimationOptions.CurveEaseInOut, animations: 
        gradientLayer.colors = colors
        , completion: nil)


如何调整上面的代码以将渐变层从一个渐变到另一个? (不相关 - 在子层上不断“添加子层”对内存有害吗?)

【问题讨论】:

是的,不断添加更多子层是不好的。您应该创建一个渐变层,然后修改其属性以更新渐变。如果您仍然遇到问题,请修复该问题,然后返回并使用新代码更新您的问题。 @robmayoff - 哎呀。很高兴我抓住了!这里的修复是否像从 configureGradient 函数中删除 self.layer.addSublayer(gradientLayer) 并将其移动到 prepareGradient 一样简单? (我在上面编辑了我的代码。) 【参考方案1】:

这将起作用:

func configureGradient(colors:[CGColor]) 
    let gradientLayer = prepareGradient()
    gradientLayer.colors = colors
    UIView.transitionWithView(self,
                              duration: 0.25,
                              options: UIViewAnimationOptions.TransitionCrossDissolve,
                              animations:  [weak self] () -> Void in
                                self?.layer.addSublayer(gradientLayer)
        , completion: nil)

...无论如何添加子层只是为了改变颜色并不酷。 尝试将渐变层存储在扩展中:

private struct AssociatedKeys 
    static var gradientLayer = CAGradientLayer()


var gradientLayer: CAGradientLayer 
    get 
        guard let gLayer = objc_getAssociatedObject(self, &AssociatedKeys.gradientLayer) as? CAGradientLayer else  return CAGradientLayer() 
        return gLayer
    
    set(value) 
        objc_setAssociatedObject(self, &AssociatedKeys.gradientLayer, value, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
    

可能是 UIView 子类实现起来更简单...我认为你应该这样做。

【讨论】:

这确实有效,是的!但是,我的初始代码中存在一个连续堆叠子层的错误。我正在尝试在我的初始代码中解决这个问题,然后尝试添加这个淡入淡出。

以上是关于Swift - 使用 animateWithDuration 淡化 CAGradientLayer的主要内容,如果未能解决你的问题,请参考以下文章

Swift 上的块 (animateWithDuration:animations:completion:)

Swift UIView.animateWithDuration [重复]

UiView.animateWithDuration 不为 Swift3 设置动画

当使用动画块内函数的参数时,Swift 无法解析 UIView.animateWithDuration 中的 CurveEaseIn

swift animateWithDuration 在 iOS 7 中不起作用

Swift:缺少参数的参数