您应该继承 UIView 以创建 GradientView 类。添加一个数组来保存您正在移动的颜色。选择很重要,我写了一篇文章解释了原因。覆盖drawRect(rect: CGRect)方法并在颜色的组件之间进行插值:
override func drawRect(rect: CGRect) {
let context = UIGraphicsGetCurrentContext();
CGContextSaveGState(context);
let c1 = colors[index == 0 ? (colors.count - 1) : index - 1] // previous
let c2 = colors[index] // current
let c3 = colors[index == (colors.count - 1) ? 0 : index + 1] // next
var c1Comp = CGColorGetComponents(c1.CGColor)
var c2Comp = CGColorGetComponents(c2.CGColor)
var c3Comp = CGColorGetComponents(c3.CGColor)
var colorComponents = [
c1Comp[0] * (1 - factor) + c2Comp[0] * factor, // color 1 and 2
c1Comp[1] * (1 - factor) + c2Comp[1] * factor,
c1Comp[2] * (1 - factor) + c2Comp[2] * factor,
c1Comp[3] * (1 - factor) + c2Comp[3] * factor,
c2Comp[0] * (1 - factor) + c3Comp[0] * factor, // color 2 and 3
c2Comp[1] * (1 - factor) + c3Comp[1] * factor,
c2Comp[2] * (1 - factor) + c3Comp[2] * factor,
c2Comp[3] * (1 - factor) + c3Comp[3] * factor
]
let gradient = CGGradientCreateWithColorComponents(CGColorSpaceCreateDeviceRGB(), &colorComponents, [0.0, 1.0], 2)
let startPoint = CGPoint(x: 0.0, y: 0.0)
let endPoint = CGPoint(x: rect.size.width, y: rect.size.height)
CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, CGGradientDrawingOptions.DrawsAfterEndLocation)
CGContextRestoreGState(context);
}
index 变量从 0 开始并环绕颜色数组,而因子在 0.0 和 1.0 之间并通过计时器进行动画处理:
var index: Int = 0
var factor: CGFloat = 1.0
var timer: NSTimer?
func animateToNextGradient() {
index = (index + 1) % colors.count
self.setNeedsDisplay()
self.factor = 0.0
self.timer = NSTimer.scheduledTimerWithTimeInterval(1.0/60.0, target: self, selector: "animate:", userInfo: nil, repeats: true)
}
func animate(timer: NSTimer) {
self.factor += 0.02
if(self.factor > 1.0) {
self.timer?.invalidate()
}
self.setNeedsDisplay()
}