SwiftUIではforegroundColorを使用する事で色を変更する事ができますが、Assetsに用意したImageはrenderingModeでtemplateを指定しないとforegroundColorで指定した色を反映させる事ができません。 今回はrenderingModeのtemplateで色んなファイル形式の違うImageにて色を変更させてみました。
renderingMode
renderingとは元のデータを整形して出力することで、SwiftUIではAssetsで用意したImageはrenderingModeでtemplate を定義することで指定した色を反映させる事ができます。
以下モードとそれぞれの説明です。
renderingMode | 内容 |
---|---|
original | ビットマップ画像のピクセルをそのままレンダリングするモード。 |
template | すべての不透明なピクセルを前景色としてレンダリングするモード。 |
使用例
とりあえずpng形式のImageを用意して試しました。
original
Image("pngImage")
.renderingMode(.original)
.foregroundColor(Color.red)
.background(Color.blue)
背景色は反映さえれていますが図の色はそのままレンダリングされています。
template
Image("pngImage")
.renderingMode(.template)
.foregroundColor(Color.red)
.background(Color.blue)
図の色も反映されています。
その他ファイル形式
予想ではpng、svgのみうまくいくと思っていましたがpdfでも普通に反映されていました!
(確かにpdfにもラスタやベクタがあるのでできるのか)
jpegは予想通り背景も全てベタ塗りになりました!
Sample(作ってみた)
せっかくなので色んな色のImageを散りばめてぼかして背景っぽい画像を作ってみました。
class RandomColorGenerator: ObservableObject { private var redAmount:Double = 0.0 private var greenAmount: Double = 0.0 private var blueAmount: Double = 0.0 @Published var randomColor: Color = Color(red: 1.0, green: 1.0, blue: 1.0) func randomColorGenerator() { redAmount = Double.random(in: 0.0000000...1) greenAmount = Double.random(in: 0.0000000...1) blueAmount = Double.random(in: 0.0000000...1) randomColor = Color (red: redAmount, green: greenAmount, blue: blueAmount, opacity: 0.4) } }
Imageに対してランダムな色付けをするViewのコンポーネントを作成。
struct ImageView: View { @ObservedObject private var colorGenerator = RandomColorGenerator() var body: some View { Image("pngImage") .renderingMode(.template) .resizable() .frame(width: 50, height: 50) .foregroundColor(colorGenerator.randomColor) .onAppear() { colorGenerator.randomColorGenerator() } } }
先ほどのViewコンポーネントをを50枚繰り返し処理で重ねていく。
struct ImageDisplayView: View { private let halfScreenWidthSize = UIScreen.main.bounds.width / 2 private let halfScreenHeigthSize = UIScreen.main.bounds.height / 2 var body: some View { ZStack { ForEach (0..<50) { item in ImageView() .offset(x: CGFloat.random(in: -halfScreenWidthSize...halfScreenWidthSize), y: CGFloat.random(in: -halfScreenHeigthSize...halfScreenHeigthSize)) } } } } 全く実用的ではないですができました!笑
おまけ(UIImage)
UIImageで使用したい場合は以下のようにwithRenderingModeを使用する事でtintColorで指定した色を反映させる事ができます。
let uiImage = UIImage(named: "imageName")?.withRenderingMode(.alwaysTemplate)
参考記事