You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SwiftUI中如何在Canvas内的文本下方填充匹配尺寸的矩形

在SwiftUI Canvas中获取文本尺寸并绘制内缩背景矩形

在SwiftUI的Canvas里直接操作Text视图无法获取尺寸,因为Canvas中的Text是作为图形符号处理的,不是常规的View类型。你需要通过GraphicsContext提供的解析和测量API来实现需求,下面是修正后的代码:

struct ContentView: View {
    var body: some View {
        Canvas { context, size in
            let targetText = Text("Some text").foregroundColor(.black)
            
            // 解析文本符号,得到可测量的实例
            let resolvedText = context.resolveSymbol(targetText)
            // 获取文本的原始边界矩形
            let textBounds = resolvedText.boundingRect(in: .infinite)
            
            // 计算向外扩展后的背景矩形(dx/-4、dy/-2表示在文本基础上左右各加4pt,上下各加2pt)
            let backgroundSize = textBounds.size.insetBy(dx: -8, dy: -4)
            // 计算背景和文本的居中位置
            let centerPoint = CGPoint(x: size.width/2, y: size.height/2)
            let backgroundRect = CGRect(
                x: centerPoint.x - backgroundSize.width/2,
                y: centerPoint.y - backgroundSize.height/2,
                width: backgroundSize.width,
                height: backgroundSize.height
            )
            
            // 先绘制背景矩形
            context.fill(backgroundRect, with: .color(.red))
            // 再绘制文本,确保文本在背景上方
            context.draw(targetText, at: centerPoint)
        }
    }
}

关键说明:

  • 必须通过context.resolveSymbol(_:)解析Text,得到GraphicsContext.ResolvedSymbol实例后才能调用boundingRect(in:)获取尺寸,直接操作Text视图没有这个属性。
  • 使用.infinite作为测量容器,能让文本以自然尺寸排列,不受限制。
  • 绘制顺序要注意:先画背景再画文本,避免文本被背景遮挡。
  • 如果你更倾向于使用富文本,也可以用AttributedString配合context.measure(_:in:)来获取尺寸,效果一致:
    let attributedText = AttributedString("Some text")
    let textBounds = context.measure(attributedText, in: .infinite)
    

内容的提问来源于stack exchange,提问作者andrewz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 10:15:10