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

SwiftUI中如何在UIImage上绘制完整长文本?

解决UIImage上绘制多行文本的问题

修改后的完整代码

struct ContentView: View {
    @State var bottomImage = UIImage(named: "2")
    let text = "SwiftUI helps you build great-looking apps across all Apple platforms with the power of Swift — and surprisingly little code."
    var body: some View {
            VStack{
                Image(uiImage: bottomImage!)
                    .resizable()
                    .scaledToFit()
                Button {
                    drawTextOnImage()
                } label: {
                    Text("DrawText")
                }
            }
    }
    func drawTextOnImage(){
        let newSize = CGSize(width: 660, height: 700)
        guard let topNew = UIImage(named: "3") else { return }

        UIGraphicsBeginImageContextWithOptions(newSize, false, 0.0)
        topNew.draw(in: CGRect(origin: .zero, size: newSize))
        
        let font = UIFont.systemFont(ofSize: 40)
        let textStyle = NSMutableParagraphStyle()
        textStyle.lineBreakMode = .byWordWrapping // 改为按单词换行
        textStyle.numberOfLines = 0 // 允许无限行数
        textStyle.alignment = .center
        let textColor = UIColor.yellow
        let attributes: [NSAttributedString.Key: Any] = [
            .font: font,
            .paragraphStyle: textStyle,
            .foregroundColor: textColor
        ]
        
        // 计算文本在指定宽度下的实际高度
        let maxTextWidth = topNew.size.width
        let textBoundingBox = text.boundingRect(
            with: CGSize(width: maxTextWidth, height: .greatestFiniteMagnitude),
            options: .usesLineFragmentOrigin,
            attributes: attributes,
            context: nil
        )
        let textHeight = textBoundingBox.height
        let textY = (topNew.size.height - textHeight) / 1.2 // 保持垂直位置计算
        let textRect = CGRect(x: 0, y: textY, width: maxTextWidth, height: textHeight)
        
        text.draw(in: textRect.integral, withAttributes: attributes)
        let newImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        
        DispatchQueue.main.async {
            self.bottomImage = newImage
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

关键修改点

  • 段落样式调整:将lineBreakMode从.byTruncatingTail改为.byWordWrapping,并启用numberOfLines = 0,允许文本自动换行显示多行内容。
  • 文本高度计算:使用boundingRect(with:options:attributes:context:)方法,根据文本内容和指定宽度计算实际需要的高度,确保文本矩形区域足够容纳所有行。
  • 安全可选值处理:添加guard let避免强制解包导致的崩溃。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 04:10:32