Swift - CAGradientLayer渐变动画的实现2(彩虹动画圆环)
作者:hangge | 2017-09-11 08:10
1,效果图
(1)圆环的背景显示的是彩虹色的渐变。
(2)整个渐变背景不是固定不动的,而是会从左上角往右下角方向不断地循环移动。

(2)主视图控制器(ViewController.swift)
源码下载:
hangge_1789.zip

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()
}
}
源码下载:
全部评论(0)