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

Swift4 iOS开发者:如何仅用UIKit实现UILabel/UIView文字弯曲

纯UIKit实现文字沿圆弧弯曲的自定义标签

嘿,我完全懂你的需求——已经搞定了圆形的UILabel,但想让文字跟着圆弧弯曲,还不想碰SpriteKit,只靠UIKit来实现对吧?其实咱们可以直接基于UIView做一个自定义子类,用Core Graphics(UIKit的底层绘图框架)来绘制沿圆弧排列的文字,完全不用依赖游戏相关的框架。

下面是具体的实现方案,直接贴代码,每部分我都会给你解释清楚:

import UIKit

class CurvedLabel: UIView {
    // 可配置的属性,方便你调整样式
    var text: String = "Hello Curved Text" {
        didSet { setNeedsDisplay() }
    }
    var textColor: UIColor = .black {
        didSet { setNeedsDisplay() }
    }
    var font: UIFont = .systemFont(ofSize: 16) {
        didSet { setNeedsDisplay() }
    }
    // 圆弧的半径,默认取视图宽高中较小值的一半
    var arcRadius: CGFloat? {
        didSet { setNeedsDisplay() }
    }
    
    override func draw(_ rect: CGRect) {
        super.draw(rect)
        guard let context = UIGraphicsGetCurrentContext(), !text.isEmpty else { return }
        
        // 计算实际使用的圆弧半径
        let radius = arcRadius ?? min(bounds.width, bounds.height) / 2.0
        // 圆弧的中心就是视图的中心
        let center = CGPoint(x: bounds.midX, y: bounds.midY)
        // 计算文字总宽度,用来确定起始角度,让文字居中
        let textSize = text.size(withAttributes: [.font: font])
        let totalTextWidth = textSize.width
        // 每个字符对应的角度增量(弧度)
        let anglePerCharacter = totalTextWidth / radius
        // 起始角度:让文字整体居中,这里是向上弯曲的圆弧(如果要向下弯,把-.pi/2改成.pi/2)
        var currentAngle = -.pi/2 - anglePerCharacter / 2.0
        
        // 设置文本属性
        let attributes: [NSAttributedString.Key: Any] = [
            .font: font,
            .foregroundColor: textColor
        ]
        
        // 遍历每个字符,逐个绘制到圆弧上
        for character in text {
            let charString = String(character)
            let charSize = charString.size(withAttributes: attributes)
            
            // 保存当前上下文状态,避免旋转影响后续绘制
            context.saveGState()
            
            // 移动上下文到圆弧上的对应位置
            context.translateBy(x: center.x, y: center.y)
            context.rotate(by: currentAngle)
            context.translateBy(x: radius - charSize.width/2, y: 0)
            
            // 绘制字符
            charString.draw(at: .zero, withAttributes: attributes)
            
            // 恢复上下文状态
            context.restoreGState()
            
            // 更新下一个字符的角度
            currentAngle += charSize.width / radius
        }
    }
}

代码解释:

  • 我们创建了CurvedLabel这个UIView子类,把文本、颜色、字体、圆弧半径都做成了可配置的属性,修改后会自动触发重绘。
  • 在draw(_:)方法里,先计算圆弧的中心和半径,再根据文字总宽度算出每个字符应占据的角度,确保文字整体居中显示。
  • 遍历每个字符时,通过旋转和移动图形上下文,让每个字符都沿着圆弧的切线方向排列,视觉上就呈现出文字跟随圆弧弯曲的效果。
  • 如果想要文字向下弯曲(类似碗状弧度),只需要把起始角度的-.pi/2改成.pi/2即可。

使用方法:

你可以像使用普通UIView一样,在代码或Storyboard中创建这个自定义视图:

// 代码创建示例
let curvedLabel = CurvedLabel(frame: CGRect(x: 50, y: 200, width: 300, height: 300))
curvedLabel.text = "我是弯曲的文字"
curvedLabel.font = .boldSystemFont(ofSize: 20)
curvedLabel.textColor = .darkGray
curvedLabel.arcRadius = 120
view.addSubview(curvedLabel)

这种方式完全基于UIKit和Core Graphics,没有用到任何SpriteKit的API,完美符合你的需求~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 07:51:19