返回 导航

Swift

hangge.com

Swift - CAGradientLayer渐变动画的实现2(彩虹动画圆环)

作者:hangge | 2017-09-11 08:10

1,效果图

(1)圆环的背景显示的是彩虹色的渐变。
(2)整个渐变背景不是固定不动的,而是会从左上角往右下角方向不断地循环移动。
 
           

2,实现方式

(1)使用 CAGradientLayer 创建一个彩虹色的渐变(方向从左上角到右下角),然后绘制一个圆环作为它的遮罩,便实现了一个彩虹色的圆环。
(2)接着通过 CABasicAnimation 实现一个动画,将渐变色数组中的最后一个颜色元素移到第一个位置,这样动画播放时看起来就像是渐变层往右下方移动。
(3)最后在动画结束方法中再重复执行上面的动作,便实现了无限循环轮播移动的动画。

3,样例代码

(1)彩虹圆环组件(RainbowRing.swift
import UIKit

class RainbowRing: UIView, CAAnimationDelegate {
    //每次动画变化的时长
    let duration = 0.1
    
    //圆环宽度
    let ringWidth:CGFloat = 20
    
    //渐变层
    var gradientLayer: CAGradientLayer!
    
    //遮罩层
    var maskLayer:CAShapeLayer!
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        
        //创建彩虹渐变层
        gradientLayer =  CAGradientLayer()
        gradientLayer.frame = bounds
        gradientLayer.startPoint = CGPoint(x: 0.0, y: 0.0)
        gradientLayer.endPoint = CGPoint(x: 1.0, y: 1.0)
        
        //设置渐变层的颜色
        var rainBowColors:[CGColor] = []
        var hue:CGFloat = 0
        while hue <= 360 {
            let color = UIColor(hue: 1.0*hue/360.0, saturation: 1.0, brightness: 1.0,
                                alpha: 1.0)
            rainBowColors.append(color.cgColor)
            hue += 5
        }
        gradientLayer.colors = rainBowColors
        
        //添加渐变层
        self.layer.addSublayer(gradientLayer)
        
        //创建遮罩层(使用贝塞尔曲线绘制)
        maskLayer = CAShapeLayer()
        maskLayer.path = UIBezierPath(ovalIn:
            bounds.insetBy(dx: ringWidth/2, dy: ringWidth/2)).cgPath
        maskLayer.strokeColor = UIColor.gray.cgColor
        maskLayer.fillColor = UIColor.clear.cgColor
        maskLayer.lineWidth = ringWidth
        
        //设置遮罩
        gradientLayer.mask = maskLayer
        
        //开始播放动画
        performAnimation()
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    //动画播放结束后的响应
    func animationDidStop(_ anim: CAAnimation, finished flag: Bool) {
        //继续播放动画
        performAnimation()
    }
    
    //执行动画
    func performAnimation() {
        //更新渐变层的颜色
        let fromColors = gradientLayer.colors as! [CGColor]
        let toColors = self.shiftColors(colors: fromColors)
        gradientLayer.colors = toColors
        //创建动画实现渐变颜色从左上向右下移动的效果
        let animation = CABasicAnimation(keyPath: "colors")
        animation.duration = duration
        animation.fromValue = fromColors
        animation.toValue = toColors
        //动画完成后是否要移除
        animation.isRemovedOnCompletion = true
        animation.fillMode = kCAFillModeForwards
        animation.timingFunction = CAMediaTimingFunction(name:
            kCAMediaTimingFunctionLinear)
        animation.delegate = self
        //将动画添加到图层中
        gradientLayer.add(animation, forKey: "colors")
    }
    
    //将颜色数组中的最后一个元素移到数组的最前面
    func shiftColors(colors:[CGColor]) -> [CGColor] {
        //复制一个数组
        var newColors: [CGColor] = colors.map{($0.copy()!) }
        //获取最后一个元素
        let last: CGColor = newColors.last!
        //将最后一个元素删除
        newColors.removeLast()
        //将最后一个元素插入到头部
        newColors.insert(last, at: 0)
        //返回新的颜色数组
        return newColors
    }
}

(2)主视图控制器(ViewController.swift
import UIKit

class ViewController: UIViewController, CAAnimationDelegate {
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        //创建彩虹动画圆环
        let frame = CGRect(x:50, y:80, width:160, height:160)
        let rainbowRing = RainbowRing(frame:frame)
        self.view.addSubview(rainbowRing)
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
}

源码下载hangge_1789.zip
评论

全部评论(0)

回到顶部