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
相关产品推荐
相关产品推荐

