#はじめに
Xcode9の正式版がリリースされてから約3ヶ月経ちますが、皆さんは追加された新機能を使用していますか?
今回は、追加された機能のうちの"ColorSet"について調べてみたので、備忘録として投稿してみようと思います。
なお、Qiita初投稿となります。生温かい目でネットリ見守って頂けると幸いです。
#そもそもColorSetとは
Xcode Release Notesによると、
Asset Catalog
New Features
Asset catalogs now support named colors that can be used in source files and Interface Builder. (28900538)
Xcode9.0から、ソースコード上やIB上から使用できる色定義が作成できるようになった、とのこと。
使用するにはBuild TargetをiOS11以上にする必要があるようです。
#色定義の作り方
- AssetCatalogファイルを選択します
- 画面左下の「+」ボタンを押し、メニューを表示します。
- メニュー内の「New Color Set」を選択します。
これで、「Color」という名前の色定義が新たに作成されます。
- 画像左側エディタエリアで、ColorSetの名前を変更することができます。
- 画像右側ユーティリティエリアで、Color SpaceやInput Methodを変更することができます。Colorで直接色を指定することもできます。
#実際に使ってみた
今回は
- Redを0.4 Greenを0.7 Blueを1.0で定義したLightBlue
- Redを1.0 Greenを0.7 Blueを0.4で定義したLightOrange
InterfaceBuilderで使用する場合、色を指定する際に「Named Colors」の欄が追加されており、そこから選択できるようになっています。
ソースコードで使用する場合は以下のイニシャライザを使うようです。
extension UIColor {
@available(iOS 11.0, *)
public /*not inherited*/ init?(named name: String) // load from main bundle
@available(iOS 11.0, *)
public /*not inherited*/ init?(named name: String, in bundle: Bundle?, compatibleWith traitCollection: UITraitCollection?)
}
#データ構造
##AssetCatalogデータ
まずColorSetを作成するとAssets.xcassets内に<色定義名>.colorset/Contents.json
というファイルが作成されます。先程作成したLightBlueの場合、以下のようになります。
{
"info" : {
"version" : 1,
"author" : "xcode"
},
"colors" : [
{
"idiom" : "universal",
"color" : {
"color-space" : "srgb",
"components" : {
"red" : "0.400",
"alpha" : "1.000",
"blue" : "1.000",
"green" : "0.700"
}
}
}
]
}
なお、Input Methodの情報は"color-space"
のようには保持しておらず、上記のColorSetの設定をFloatingPoint(0.0-1.0)
から8bit(0-255)
に変更すると
{
"info" : {
"version" : 1,
"author" : "xcode"
},
"colors" : [
{
"idiom" : "universal",
"color" : {
"color-space" : "srgb",
"components" : {
"red" : "102",
"alpha" : "1.000",
"blue" : "255",
"green" : "178"
}
}
}
]
}
となりました。また、8-bit(Hexadecimal)
にした場合は"red" : "0x66"
のようになります。
##InterfaceBuilderでのデータ
ViewController
のView
の背景色にWhiteColor
をセットした状態から、先程定義したLightBlue
に変更してみると、以下のような差分が出ます。
@@ -6,6 +6,7 @@
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13527"/>
+ <capability name="Named colors" minToolsVersion="9.0"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
@@ -17,7 +18,7 @@
<view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
- <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
+ <color key="backgroundColor" name="LightBlue"/>
<viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/>
</view>
</viewController>
@@ -25,4 +26,9 @@
</objects>
</scene>
</scenes>
+ <resources>
+ <namedColor name="LightBlue">
+ <color red="0.40000000000000002" green="0.69803921568627447" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+ </namedColor>
+ </resources>
</document>
設定した時点で、色の内容のコピーが作成される様ですね。
#残念なところ
##その1
AssetCatalogとInterfaceBuilderを両方開いた状態でAssetCatalogの色を変更しても、InterfaceBuilderの表示には反映されませんでした。ただし、ビルドすると反映されていました。
一度プロジェクトを閉じ、再度開くと、InterfaceBuilder上に反映されていました。もちろんビルドした画面にも反映されていました。
##その2
「その1」の操作を行った時、Main.storyboard
に差分が一切発生しませんでした。つまり、色の内容のコピーは、InterfaceBuilder上で設定したタイミングに作成され、AssetCatalogの定義に追従して変更してくれるわけではない模様です。
そのため、「その1」の後にAssetCatalogの定義を消してみたところ、コピーが作成された時点のオレンジ色が表出してしまいました。
色定義を変更する場合や削除する場合、grep
をかけてあげるなど、工夫が必要がそうです。
#おわりに
Xcode9から追加されたsafe areaなど、完全に理解できていない要素がまだまだたくさんあるため、今後はそちらについても勉強していこうと思っています。