I'm trying to draw text with a filled and inset rectangle under the text that matches the text's size inside a Canvas
in SwiftUI
, but I'm unable to figure out how to get the dimensions of the Text
view.
struct ContentView: View {
var body : some View {
Canvas { context,size in
let TEXT = Text("Some text").foregroundColor(.black)
// context.fill(TEXT.boundingRect.insetBy(dx: -4, dy: -2), with: .color(.red)) // error: no boundingRect
context.draw(TEXT, at: CGPoint(x: size.width/2,y: size.height/2))
}
}
}
You need ask the GraphicsContext
to ‘resolve’ the Text
. You can then ask the ResolvedText
to measure itself.
struct ContentView: View {
var body: some View {
Canvas { gc, size in
let text: Text = Text("some text")
.foregroundColor(.black)
let resolvedText = gc.resolve(text)
let textSize = resolvedText.measure(in: size)
let textRect = CGRect(
x: 0.5 * (size.width - textSize.width),
y: 0.5 * (size.height - textSize.height),
width: textSize.width,
height: textSize.height
)
let bgRect = textRect.insetBy(dx: -5, dy: -5)
gc.fill(Path(bgRect), with: .color(.mint))
gc.draw(resolvedText, in: textRect)
}
}
}
Output:
I found that I needed to make the type of the text
variable explicit (let text: Text
). Otherwise, the compiler infers type some View
, which can't be resolved.