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

SwiftUI实现Apple Game Center风格圆形成就视图

SwiftUI 实现 Game Center 风格圆形成就视图

核心思路

解决环形文本对齐和弧线标题的关键是利用几何计算定位字符和路径文本渲染,替代单纯的旋转Text视图。下面分组件实现,再整合为完整视图。

1. 顶部环形排列文本

通过拆分文本为单个字符,结合几何计算确定每个字符的旋转角度和位置,确保字符沿环形均匀分布且朝向正确:

struct CircularTopText: View {
    let text: String
    let radius: CGFloat
    let fontSize: CGFloat
    
    var body: some View {
        GeometryReader { geo in
            ZStack {
                ForEach(Array(text.enumerated()), id: \.offset) { index, char in
                    Text(String(char))
                        .font(.system(size: fontSize, weight: .bold))
                        .foregroundColor(.white)
                        .position(
                            x: geo.size.width / 2 + radius * cos(angleForIndex(index)),
                            y: geo.size.height / 2 + radius * sin(angleForIndex(index))
                        )
                        .rotationEffect(Angle(radians: angleForIndex(index) + .pi / 2))
                }
            }
        }
    }
    
    private func angleForIndex(_ index: Int) -> Double {
        let totalChars = text.count
        let anglePerChar = 2 * Double.pi / Double(totalChars)
        // 让文本从顶部开始排列,调整起始角度
        return anglePerChar * Double(index) - Double.pi / 2
    }
}

2. 中心弧线环绕标题

iOS 16+ 可直接利用AttributedString的路径属性实现文本沿弧线排列,这里给出原生SwiftUI方案:

struct ArcTitle: View {
    let title: String
    let arcRadius: CGFloat
    let fontSize: CGFloat
    
    var body: some View {
        GeometryReader { geo in
            Text(attributedTitle)
                .position(x: geo.size.width / 2, y: geo.size.height / 2)
        }
    }
    
    private var attributedTitle: AttributedString {
        var attrString = AttributedString(title)
        attrString.font = .system(size: fontSize, weight: .semibold)
        attrString.foregroundColor = .white
        
        // 创建弧形路径,调整弧度让文本向上弯曲
        let path = CGMutablePath()
        path.addArc(center: .zero, radius: arcRadius, startAngle: .pi * 0.75, endAngle: .pi * 1.25, clockwise: false)
        
        attrString.path = path
        return attrString
    }
}

3. 完整成就视图整合

将两个组件与背景、中心图标等整合,形成最终效果:

struct GameCenterAchievementView: View {
    var body: some View {
        ZStack {
            // 成就背景圆
            Circle()
                .fill(LinearGradient(gradient: Gradient(colors: [.blue, .purple]), startPoint: .topLeading, endPoint: .bottomTrailing))
                .frame(width: 300, height: 300)
            
            // 顶部环形文本
            CircularTopText(text: "COMPLETE ALL CHALLENGES", radius: 130, fontSize: 12)
            
            // 中心弧线标题
            ArcTitle(title: "MASTER COLLECTOR", arcRadius: 80, fontSize: 18)
            
            // 中心图标示例
            Image(systemName: "trophy.fill")
                .font(.system(size: 60))
                .foregroundColor(.yellow)
        }
    }
}

// 预览
struct GameCenterAchievementView_Previews: PreviewProvider {
    static var previews: some View {
        GameCenterAchievementView()
    }
}

关键调整说明

  • 环形文本通过angleForIndex计算每个字符的弧度,确保从顶部开始均匀分布,旋转效果让字符始终朝向外侧
  • 弧线标题通过调整addArc的起始/结束角度,控制文本的弯曲方向和覆盖范围
  • 所有组件使用GeometryReader适配容器大小,避免硬编码位置导致的适配问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 02:52:10