とあるUdemyのSwiftの講座を受講中に
いじった「Image Set」の「Render As」が気になったので
調べてみることにしました✍️
◆ What is image rendering mode in iOS ?
iOSで画像を使用する場合、
画像をどのようにレンダリングするかを制御する機会があります。
これを制御する画像プロパティは、レンダリングモードと呼ばれます。
レンダリングモードの種類
レンダリングモードには2種類あります。
- オリジナル
- テンプレート
オリジナル
オリジナルレンダリングモードでは、画像をそのまま描画します。
テンプレート
テンプレートレンダリングモードは、
色情報を無視して画像を描画し、新しい色がすべての非透過ピクセルの上に
塗られるティンタブル画像を作成します。
以下は、同じ画像をオリジナルモードとテンプレートモードで
レンダリングした例です。
【左】オリジナルレンダリングモード 【右】テンプレートレンダリングモード
レンダリングモードの設定方法
画像のレンダリングモードは、
アセットカタログやプログラムによって設定することができます。
Asset Catalog
Asset Catalogに新しい画像を追加すると、
XcodeはそのレンダリングモードをDefaultに設定します。
デフォルトのレンダリングモードについては、後のセクションで説明します。
今現在は、優先順位がないと考えることができます。
画像のレンダリングモードは、
「属性インスペクタ」の「レンダリング方法」から選択することで変更できます。
UIKitを使ったプログラム
画像のレンダリングモードを設定するには、
UIImageのインスタンスメソッドwithRenderingMode(_:)を使用します。
このメソッドは、指定されたレンダリングモードを使用する
新しいUIImageのインスタンスを返します。
let templateImage = UIImage(named: "lamp")?.withRenderingMode(.alwaysTemplate)
SwiftUIを使ったプログラム
SwiftUIにはrenderingMode(_:)という同等のビューモディファイアがあります。
Image("lamp")
.renderingMode(.template)
テンプレートレンダリングモードは何の為にあるのか?
レンダリングモードを設定する方法を学びますが、
より重要な問題は、
なぜテンプレートレンダリングモードが必要なのかということです。
オリジナルレンダリングモードでは、
元の画像に表示されているとおりに画像をレンダリングします。
これは、製品画像やオンボーディングのイラストなど、
ほとんどの画像で期待されることかもしれません。
画像はすべて同じように作られるわけではありません。
例えば、ボタンのアイコンのように、
元の色ではなく画像の形を使いたい場合など、
イメージマスクとして使用することを目的にデザインされた画像もあります。
デフォルトのレンダリングモードとは
「アセットカタログのレンダリングモードの設定方法」では、
デフォルトのレンダリングモードが
「Default」に設定されていることがわかります。
理想的には、すべての画像のレンダリングモードを、
その画像の目的に合わせて設定するのがよいでしょう。
デフォルトに設定することは、その画像に特定の目的がなく、
オリジナルモードでもテンプレートモードでも
レンダリングできることを意味します。
レンダリングモードを指定しない場合、システムはどのように判断するのでしょうか?
画像にレンダリングモードを指定しない場合、
システムはその画像が使われていた場所のレンダリングモードに基づいて
画像を描画します。
各ビューやコントロールには、
それぞれデフォルトのレンダリングモードがあります。
このレンダリングモードはどこにも記述されていませんが、
タブバーアイテムやナビゲーションバーアイテムの
テンプレートレンダリングモードのように、
システムスタイルにマッチしたレンダリングモードとなります。
ここでは、各ビューやコントロールのデフォルトのレンダリングモードの例を示します。
let image = UIImage(named: "small-lamp")
let imageView = UIImageView(image: image)
imageView.contentMode = .center
let systemButton = UIButton(type: .system)
systemButton.setImage(image, for: .normal)
systemButton.setTitle("UIButton(type: .system)", for: .normal)
let customButton = UIButton(type: .custom)
customButton.setImage(image, for: .normal)
customButton.setTitle("UIButton(type: .custom)", for: .normal)
let barButtonItem = UIBarButtonItem(image: image, style: .plain, target: nil, action: nil)
navigationItem.rightBarButtonItem = barButtonItem
let tabBarItem = UITabBarItem(title: "Small lamp", image: image, selectedImage: nil)
self.tabBarItem = tabBarItem
画像のレンダリングモードを変更した場合、
システムはそれを尊重し、
デスティネーションビューのデフォルトのレンダリングモードを無視します。
let image = UIImage(named: "small-lamp")?.withRenderingMode(.alwaysTemplate)
オリジナルのレンダリングモードの場合はこんな感じです。
let image = UIImage(named: "small-lamp")?.withRenderingMode(.alwaysOriginal)
結論
画像レンダリングモードは、
その画像をそのまま使うという意味か、テンプレートとして使うという意味か、
その画像の目的を設定するところです。
すべての画像に対してこれを設定するのは面倒なので、
UIImageViewにはオリジナルレンダリングモード、
UITabBarItemにはテンプレートレンダリングモードというように、
各UI要素にはそのUIに適したデフォルトレンダリングモードが用意されています。
そのため、ほとんどの場合はレンダリングモードをデフォルトのままにしておき、ビューが適切なものを選択することに依存すればよいのですが、
デフォルトの動作に合致しない特定のニーズがある場合は、
レンダリングモードを設定することで制御することが可能です。
《参考記事》 What is image rendering mode in iOS