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

SwiftUI(iOS 16)中Canvas内如何围绕中心旋转文本?

解决SwiftUI Canvas中文本90°旋转问题

你的问题出在两个核心点:

  • 直接调用context.rotate会修改整个画布的坐标系,导致所有后续绘制内容都被旋转,而非仅目标文本。
  • Text的rotationEffect是SwiftUI View层级的修饰符,Canvas的context.draw在渲染View时不会识别这类变换操作——它是将View静态渲染为图形内容,不处理View的变换属性。

正确实现方式:通过Context状态管理局部旋转

利用saveState()和restoreState()隔离旋转操作的影响,配合坐标平移实现文本围绕自身中心在指定位置旋转:

Canvas { context, size in
    let textContent = String(drinkFrom)
    let textView = Text(textContent)
        .font(.custom("HelveticaNeue", size: 12))
        .foregroundColor(.textUnselected)
    
    // 保存当前画布状态,避免旋转影响其他绘制内容
    context.saveState()
    
    // 平移坐标系原点到文本目标位置
    let targetPosition = CGPoint(x: drinkFromOriginX, y: size.height/2)
    context.translateBy(x: targetPosition.x, y: targetPosition.y)
    
    // 围绕当前原点(即文本中心)旋转90°
    context.rotate(by: .degrees(90))
    
    // 在原点绘制文本,锚点设为.center,确保文本中心与目标位置重合
    context.draw(textView, at: .zero, anchor: .center)
    
    // 恢复画布初始状态
    context.restoreState()
}

原理说明

  1. saveState()会保存当前画布的坐标系、变换等状态,restoreState()则恢复到该状态,确保旋转操作仅作用于这段文本的绘制。
  2. translateBy将坐标系原点移到你想要放置文本的位置,此时旋转坐标系,文本的绘制中心就会固定在该位置,实现「围绕自身中心旋转」的效果。

备选方案:直接绘制NSAttributedString

如果不需要依赖SwiftUI的Text样式,也可以用更底层的方式绘制文本,精度更高:

Canvas { context, size in
    let textString = String(drinkFrom)
    let font = UIFont(name: "HelveticaNeue", size: 12)!
    let textColor = UIColor.textUnselected
    
    // 配置文本属性
    let attributes: [NSAttributedString.Key: Any] = [
        .font: font,
        .foregroundColor: textColor
    ]
    let attributedText = NSAttributedString(string: textString, attributes: attributes)
    
    // 计算文本尺寸,用于居中偏移
    let textSize = attributedText.size()
    
    context.saveState()
    let targetPoint = CGPoint(x: drinkFromOriginX, y: size.height/2)
    context.translateBy(x: targetPoint.x, y: targetPoint.y)
    context.rotate(by: .degrees(90))
    
    // 绘制文本时偏移半宽半高,确保中心与原点重合
    attributedText.draw(at: CGPoint(x: -textSize.width/2, y: -textSize.height/2))
    
    context.restoreState()
}

内容的提问来源于stack exchange,提问作者alex.bour

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 11:18:14