【Swift】あるUIColorからあるUIColorへ変化の途中経過のUIColorを作成する


ある`UIColor`からある`UIColor`へ変化させるときの途中経過の色を作る方法です。

僕は以下のソースコードで再現できました。

## DEMO

ちょっと伝わっているか不安なので、デモです。

![SampleChangeColor.gif](https://qiita-image-store.s3.amazonaws.com/0/47302/ee7028bd-f762-e509-c914-7abf9ddce7c8.gif "SampleChangeColor.gif")


## ソースコード

```swift:UIColorExtension.swift
import UIKit

extension UIColor {
    
    class func colorForOffsetPercentage(percentage: CGFloat, beforeColor: UIColor, afterColor: UIColor) -> UIColor {
        var beforeRGB = beforeColor.RGBForColor()
        var afterRGB = afterColor.RGBForColor()
     
        var actualRed = (afterRGB.red - beforeRGB.red) * percentage + beforeRGB.red
        var actualBlue = (afterRGB.blue - beforeRGB.blue) * percentage + beforeRGB.blue
        var actualGreen = (afterRGB.green - beforeRGB.green) * percentage + beforeRGB.green
        var actualAlpha = (afterRGB.alpha - beforeRGB.alpha) * percentage + beforeRGB.alpha
        
        return UIColor(red: actualRed, green: actualGreen, blue: actualBlue, alpha: actualAlpha)

    }
    
    func RGBForColor() -> (red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat) {
        var red: CGFloat = 0.0
        var green: CGFloat = 0.0
        var blue: CGFloat = 0.0
        var alpha: CGFloat = 0.0
        getRed(&red, green: &green, blue: &blue, alpha: &alpha)
        return (red, green, blue, alpha)
    }
}
```

`percentage`に`0.0 ~ 1.0`の間の値を入れるとその`UIColor`を返します。

## 使い方

DEMOで作った`ViewController.swift`のソースコードです。

```swift:ViewController.swift
import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var textColorLabel: UILabel!
    @IBOutlet weak var redColorLabel: UILabel!
    @IBOutlet weak var greenColorLabel: UILabel!
    @IBOutlet weak var blueColorLabel: UILabel!
    @IBOutlet weak var slider: UISlider!
    
    private let beforeColor: UIColor = UIColor.blueColor()
    private let afterColor: UIColor = UIColor.greenColor()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        slider.minimumValue = 0
        slider.maximumValue = 1
        slider.value = 0
        slider.addTarget(self, action: "didChangeValue:", forControlEvents: UIControlEvents.ValueChanged)
        viewTextColorLabel(percentage: 0.0)
        viewRGBColorLabel(percentage: 0.0)
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

}

extension ViewController {
    
    func didChangeValue(sender: UISlider) {
        let percentage = CGFloat(sender.value)
        viewTextColorLabel(percentage: percentage)
        viewRGBColorLabel(percentage: percentage)
    }
    
    private func viewTextColorLabel(#percentage: CGFloat) {
        textColorLabel.textColor = UIColor.colorForOffsetPercentage(percentage, beforeColor: beforeColor, afterColor: afterColor)
    }
    
    private func viewRGBColorLabel(#percentage: CGFloat) {
        let color = UIColor.colorForOffsetPercentage(percentage, beforeColor: beforeColor, afterColor: afterColor)
        let colorRGB = color.RGBForColor()
        redColorLabel.text = "R: \((colorRGB.red * 255.0))"
        greenColorLabel.text = "G: \((colorRGB.green * 255.0))"
        blueColorLabel.text = "B: \((colorRGB.blue * 255.0))"
    }
    
}
```

## 説明

ソースコード自体は特に難しいことをしていないので、これを作った背景でもお話ししたいと思います。

実際にある色からある色へ変化させるときはアニメーションで実現できます。

`UIView`のアニメーションあたりで適当に入れ替えれば、適当に色が変わります。

しかし、今回僕がやりたかったのは`UIScrollView`のスクロール量によって色を変えたかったので、このような処理が必要でした。

## 終わりに

うまくできたので、それの共有でした。