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

Swift中如何在CoreGraphics绘制的饼图扇区内添加文本?

解决饼图扇区内文本定位问题

要在每个饼图扇区中正确放置文本,核心是基于扇区的中间角度计算文本位置,同时调整文本的偏移半径避免超出扇区,以下是修改后的完整实现:

首先确保你已定义包含标签字段的Segment结构体:

struct Segment {
    let value: CGFloat
    let color: UIColor
    let label: String // 扇区对应的文本标签
}

然后修改draw(_:)方法,加入文本绘制逻辑:

override func draw(_ rect: CGRect) {
    guard let ctx = UIGraphicsGetCurrentContext() else { return }
    
    let radius = min(frame.size.width, frame.size.height) * 0.5
    let viewCenter = CGPoint(x: bounds.midX, y: bounds.midY)
    let totalValue = segments.reduce(0, {$0 + $1.value})
    var startAngle = -CGFloat.pi * 0.5 // 从顶部开始绘制饼图
    
    // 文本样式配置,可按需调整字体、颜色
    let textAttributes: [NSAttributedString.Key: Any] = [
        .font: UIFont.systemFont(ofSize: 12),
        .foregroundColor: UIColor.white
    ]
    
    let textRadius = radius * 0.7 // 文本距离中心的半径,取饼图半径的70%避免超出扇区
    
    for segment in segments {
        // 绘制饼图扇区
        let endAngle = startAngle + 2 * .pi * (segment.value / totalValue)
        ctx.setFillColor(segment.color.cgColor)
        ctx.move(to: viewCenter)
        ctx.addArc(center: viewCenter, radius: radius, startAngle: startAngle, endAngle: endAngle, clockwise: false)
        ctx.fillPath()
        
        // 计算文本的中心位置
        let midAngle = startAngle + (endAngle - startAngle) / 2 // 取扇区的中间角度
        let textX = viewCenter.x + textRadius * cos(midAngle)
        let textY = viewCenter.y + textRadius * sin(midAngle)
        let textCenterPoint = CGPoint(x: textX, y: textY)
        
        // 让文本居中绘制在计算出的位置上
        let textSize = segment.label.size(withAttributes: textAttributes)
        let textRect = CGRect(
            x: textCenterPoint.x - textSize.width / 2,
            y: textCenterPoint.y - textSize.height / 2,
            width: textSize.width,
            height: textSize.height
        )
        segment.label.draw(in: textRect, withAttributes: textAttributes)
        
        startAngle = endAngle
    }
}

关键逻辑说明

  • 中间角度定位:用扇区起始角和结束角的平均值计算文本位置,确保文本落在扇区的中心线上,不会偏移到其他扇区。
  • 文本半径调整:通过radius * 0.7控制文本与圆心的距离,既不会太靠近圆心拥挤,也不会超出扇区边缘。
  • 文本居中对齐:先计算文本自身尺寸,再将文本的中心与计算出的坐标点对齐,保证文本在扇区内居中显示。

小扇区文本重叠优化建议

如果遇到极小扇区导致文本重叠的情况,可以:

  • 根据扇区角度动态调整字体大小(比如角度小于π/12时缩小字体或隐藏文本)
  • 将小扇区的文本移到饼图外部,添加连接线指向对应扇区(需要额外实现连接线绘制逻辑)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 00:43:08