try! Swift Tokyo 2019
初日を終えて、楽しかったです!
個人的に一番刺さったセッションが、Liz Marletさんの「アクセシビリティのためのカラーコントラスト」(PDF)でした。
というのも、個人でリリースしているアプリの中にただカラーコードを表示させるだけのものがあり、暇な移動時間に作ってリリースして以来完全に放置していたので、これにコントラスト比が表示される機能を足したら良いんじゃない?
と思ったからです。
License
とはいえ、勝手にコードをコピペ実装するのはダメ、絶対!
ということでセッション終了後通路にいたLizさんを捕まえて拙い英語で「May I use your code in my app?」って聞いてみました。
心優しいLizさんは快諾いただき、使う前にコードをチェックした方が良いかも、というアドバイスまでいただけました。
それはもう女神でした。
という事で実装
ここは胸を張ってLizさんのコードをコピペします。
だって、いいって言ったんだもん!
func relativeLuminance(_ color: CGColor) -> CGFloat {
let sRGBColorSpace = CGColorSpaceMakeSRGB // ???
let sRGB = color.converted(to: sRGBColorSpace,
intent: .defaultIntent,
options: nil)!.components!
let adjusted = sRGB.map { (c) -> CGFloat in
if c <= 0.03928 { return c / 12.92
} else { return pow((c + 0.055)/1.055, 2.4) }
}
return 0.2126 * adjusted[0] +
0.7152 * adjusted[1] +
0.0722 * adjusted[2]
}
func contrastRatio(_ foreground: CGColor, _ background: CGColor) -> CGFloat {
let ratio = (foreground + 0.05) / (background + 0.05)
return ratio > 1 ? ratio : 1 / ratio
}
そうですよね、コピペで新機能が実装できるなんてそんなうまい話ないですよね。
という事で誠に僭越ながら、手元環境でコンパイルできるように少し書き換えさせていただき、勝手なワガママで最後のratioが小数点第二位で丸められるようにしました。
func relativeLuminance(_ color: CGColor) -> CGFloat {
let sRGBColorSpace = CGColorSpace(name: CGColorSpace.extendedSRGB)!
let sRGB = color.converted(to: sRGBColorSpace,
intent: .defaultIntent,
options: nil)!.components!
let adjusted = sRGB.map { (c) -> CGFloat in
if c <= 0.03928 { return c / 12.92
} else { return pow((c + 0.055)/1.055, 2.4) }
}
return 0.2126 * adjusted[0] +
0.7152 * adjusted[1] +
0.0722 * adjusted[2]
}
func contrastRatio(_ foreground: CGColor, _ background: CGColor) -> CGFloat {
let ratio = (relativeLuminance(foreground) + 0.05) / (relativeLuminance(background) + 0.05)
let result = ratio > 1 ? ratio : 1 / ratio
return round(result * 100) / 100
}
これで無事手元環境でビルドすることができました。
最後にLizさんのアドバイスに忠実に従い、テストを少々。。。
func testContrastRatioWhite() {
let vc = ViewController()
let color1 = UIColor.white.cgColor
let color2 = UIColor.black.cgColor
let ratio = vc.contrastRatio(color1, color2)
XCTAssertEqual(ratio, 21.0)
}
func testContrastRatioBlue() {
let vc = ViewController()
let color1 = UIColor.black.cgColor
let color2 = UIColor.blue.cgColor
let ratio = vc.contrastRatio(color1, color2)
XCTAssertEqual(ratio, 2.44)
}
func testContrastRatioRed() {
let vc = ViewController()
let color1 = UIColor.red.cgColor
let color2 = UIColor.black.cgColor
let ratio = vc.contrastRatio(color1, color2)
XCTAssertEqual(ratio, 5.25)
}
func testContrastRatioGreen() {
let vc = ViewController()
let color1 = UIColor.black.cgColor
let color2 = UIColor.green.cgColor
let ratio = vc.contrastRatio(color1, color2)
XCTAssertEqual(ratio, 15.30)
}
func testContrastRatioBlack() {
let vc = ViewController()
let color1 = UIColor.black.cgColor
let color2 = UIColor.black.cgColor
let ratio = vc.contrastRatio(color1, color2)
XCTAssertEqual(ratio, 1.0)
}
テストで比較する値はLizさんオススメのこちらで取得させていただきました。
これで新機能のリリースは目前です!
というわけで、