🦋
SwiftUI: GraphicsContextで任意の色のTextやImageをDrawする
SwiftUIのCanvasやImageにはGraphicsContextで動的に描画するものを制御できるAPIがあります。
例
let size = CGSize(width: 100, height: 100)
var body: some View {
Canvas { context, size in
context.draw(Text("Hello World!"), in: CGRect(origin: .zero, size: size))
context.draw(Image(systemName: "globe"), at: .zero)
}
Image(size: size) { context in
context.draw(Text("Hello World!"), in: CGRect(origin: .zero, size: size))
context.draw(Image(systemName: "globe"), at: .zero)
}
}
問題
このGraphicsContextで描画するTextやImageの色を指定したい場合にforegroundStyle()を用いると、No exact matches in call to instance method 'draw'というコンパイルエラーになります。これはforegroundStyle()モディファイアがTextやImageをViewに変換してしまうためです。
Canvas { context, size in
let text = Text("Hello World!").foregroundStyle(Color.blue)
context.draw(text, in: CGRect(origin: .zero, size: size)) // compile error
let image = Image(systemName: "globe").foregroundStyle(Color.blue)
context.draw(image, at: .zero) // compile error
}
対策
GraphicsContext.resolve()を使い、GraphicsContext.ResolvedTextやGraphicsContext.ResolvedImageとしてshadingに色を指定します。
Canvas { context, size in
var text = context.resolve(Text("Hello World!"))
text.shading = .color(.blue)
context.draw(text, in: CGRect(origin: .zero, size: size))
var image = context.resolve(Image(systemName: "globe"))
image.shading = .color(.blue)
context.draw(image, at: .zero)
}
shadingにはcolor以外にもlinearGradientやradialGradientなどのグラデーションもあるので、色々試してみると良いかもしれません。
Discussion