そーす

福岡在住のプログラマ

16進数でColorリソースを管理する

f:id:saburesan:20160427075732p:plain

saburesan.hatenablog.com

以前、R.Swiftを使ったリソース管理について少し書きました。

記事ではテキストのローカライズや画像の読み込みしか書いてないですが、他にもたくさん使えます 以下参照 github.com

しかし、R.Swiftではカラーリソースの管理が~/Library/Colors に.clrファイルを置く方法でしか使えないようでUIColorを拡張したほうが良さそうですね。

16進数をRGBに変換する

カラーコードは16進数で管理したほうが何かと便利なのですが、16進数のカラーコードをそのまま使うことはできないので、変換用メソッドを作ります。 以下完成品。 UIColorのエクステンションとして定義します。

static func toUIColor (hexStr hexStr: String, alpha: CGFloat = 1) -> UIColor {
        let hexStr = hexStr.stringByReplacingOccurrencesOfString("#", withString: "")
        let scanner = NSScanner(string: hexStr)
        var color: UInt32 = 0
        if scanner.scanHexInt(&color) {
            let r = CGFloat((color & 0xFF0000) >> 16) / 255.0
            let g = CGFloat((color & 0x00FF00) >> 8) / 255.0
            let b = CGFloat(color & 0x0000FF) / 255.0
            return UIColor(red: r, green: g, blue: b, alpha: alpha)
        } else {
            return UIColor.whiteColor()
        }
    }

順に解説します。

NSScanner

NSScannerは文字列からの検索や変換などを行うことができます。今回使っているscanHexIntは対象が16進数の場合は数値に変換して引数のポインタに格納して成功失敗を返します。

RGBの抽出

16進数から10進数の数値へ変換ができたらそこからRGBのそれぞれの値を取得します。rの変換を例に解説します。

color & 0xFF0000

この部分ですが、これはビット演算です。上位8ビットがRの値ですので、0xFF0000とのANDを取ることで取得できます。わかりやすさで16進数とのANDですが2進数とのANDでももちろん可能です

color & 0b111111110000000000000000

長い。

Rの場合下位16ビットは不要なので右にビットシフト(>>)して、Rの数値を取得します

(color & 0xFF0000) >> 16

これで実際の数値に変換できました。

UIColorにへんかんするためには0~1に正規化する必要があるので255.0で割ります。

これで16進数の変換式は完成です。

カラーリソースの定義

UIColorの実装に則って、hogeColor()->UIColor形式でエクステンションを作成します。

static func primaryColor() -> UIColor { return hex(hexStr: "#E74A3A") }

感想

なんでUIColorの定義ってプロパティじゃなくてメソッドなんですかね。