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

SwiftUI实现watchOS 11风格训练负荷评级自定义形状求助

SwiftUI实现watchOS 11训练负荷评级刻度解决方案

针对你在实现训练负荷评级刻度时遇到的梯形变形、顶部圆角特殊形状无法制作的问题,以下是具体的实现方案:

核心自定义Shape实现

通过自定义Shape分别实现普通梯形刻度块和顶部带圆角的特殊刻度块,解决形状绘制异常问题:

struct TrainingLoadScaleShape: Shape {
    // 是否为顶部带圆角的特殊块(对应「极高」等级)
    var isTopRounded: Bool
    // 梯形顶部的收窄偏移量,可根据UI调整
    var topInset: CGFloat = 12
    // 顶部圆角半径
    var cornerRadius: CGFloat = 8
    
    func path(in rect: CGRect) -> Path {
        var path = Path()
        
        // 底部左右固定点
        let bottomLeft = CGPoint(x: rect.minX, y: rect.maxY)
        let bottomRight = CGPoint(x: rect.maxX, y: rect.maxY)
        
        if isTopRounded {
            // 绘制顶部带圆角的形状
            let topMidX = rect.midX
            // 圆角左右端点,用于连接侧边
            let leftTop = CGPoint(x: topMidX - cornerRadius, y: rect.minY)
            let rightTop = CGPoint(x: topMidX + cornerRadius, y: rect.minY)
            
            path.move(to: bottomLeft)
            path.addLine(to: leftTop)
            // 添加顶部半圆圆角
            path.addArc(
                center: CGPoint(x: topMidX, y: rect.minY),
                radius: cornerRadius,
                startAngle: .degrees(180),
                endAngle: .degrees(0),
                clockwise: false
            )
            path.addLine(to: bottomRight)
            path.closeSubpath()
        } else {
            // 绘制标准梯形
            let topLeft = CGPoint(x: rect.minX + topInset, y: rect.minY)
            let topRight = CGPoint(x: rect.maxX - topInset, y: rect.minY)
            
            path.move(to: bottomLeft)
            path.addLine(to: topLeft)
            path.addLine(to: topRight)
            path.addLine(to: bottomRight)
            path.closeSubpath()
        }
        
        return path
    }
}

完整视图集成示例

将自定义Shape组合成完整的训练负荷评级视图,匹配watchOS 11的设计风格:

struct TrainingLoadRatingView: View {
    // 定义各等级的名称、颜色和形状类型
    private let loadLevels: [(name: String, color: Color, isTopRounded: Bool)] = [
        ("低", .green, false),
        ("中", .yellow, false),
        ("高", .orange, false),
        ("极高", .red, true)
    ]
    
    var body: some View {
        VStack(alignment: .leading, spacing: 6) {
            ForEach(loadLevels, id: \.name) { level in
                HStack(spacing: 10) {
                    Text(level.name)
                        .font(.caption)
                        .frame(width: 45, alignment: .leading)
                    TrainingLoadScaleShape(isTopRounded: level.isTopRounded)
                        .fill(level.color)
                        .frame(height: 26)
                }
            }
        }
        .padding(.horizontal, 16)
        .padding(.vertical, 12)
    }
}

问题修复说明

  1. 梯形异常解决:
    之前的梯形变形大概率是顶部点的坐标计算错误,比如未保持水平对称。上述代码通过基于视图边界的固定偏移量计算顶部左右点,确保梯形的上下边平行、左右对称,避免形状扭曲。

  2. 顶部圆角特殊形状解决:
    并非直接绘制三角形,而是通过「侧边+半圆圆角」的组合路径实现:先绘制底部到圆角端点的侧边,再添加180度的圆弧作为顶部圆角,最后闭合路径,完美匹配设计图中的顶部圆角效果。

你可以根据实际UI需求调整topInset、cornerRadius以及视图的spacing、frame参数,达到和官方设计完全一致的视觉效果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 22:58:28