GradientView クラスを作成するには、UIView をサブクラス化する必要があります。移動中の色を保持する配列を追加します。選択は重要であり、その理由を説明する記事を書きました。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()
}