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

SwiftUI双向用户数据进度条方向调整及填充异常问题求助

问题描述

我想要制作一个展示两位用户交互数据的进度条,样式参考指定图片。我使用了Rectangle()形状,但进度条在0.5之前呈现空白,仅在0.5之后开始填充。以下是我编写的代码:

HStack{
    ZStack(alignment: .leading){
        Rectangle()
              .trim(from:0.1, to:0.6)
            .fill(Color.init( red: 0.965, green: 0.224, blue: 0.49))
            .frame(width: 55, height: 11)
        Text(String(nowduelList.user1StepCount))
                .font(.system(size: 8))
                .bold()
                .foregroundColor(Color.white)
        }
         ZStack(alignment: .trailing){
             Rectangle()
                 .trim(from:0, to: 0.8)
                 .fill(Color.init( red: 0.208, green: 0.231, blue: 0.314))
                   .frame(width: 55, height: 11)
            Text(String(nowduelList.user2StepCount))
                .font(.system(size: 8))
                .bold()
                .foregroundColor(Color.white)
        }
    }
解决方案

问题出在trim的用法和布局结构上:

  • trim(from:to:)是裁剪形状本身,不是按比例填充进度。你当前的写法会把矩形0到0.1、0.6到1的区域剪掉,导致出现空白段。
  • 两个进度条放在HStack里是左右独立的矩形,不符合“交互进度条”(应该是一个背景上叠加双方进度)的需求。

正确实现思路:用一个总容器,内部用两个矩形分别从左右填充,文本叠加在进度条上方。修改后的代码示例:

// 先计算进度比例,避免除以0的情况
let totalSteps = nowduelList.user1StepCount + nowduelList.user2StepCount
let user1Progress = totalSteps > 0 ? CGFloat(nowduelList.user1StepCount) / CGFloat(totalSteps) : 0
let user2Progress = totalSteps > 0 ? CGFloat(nowduelList.user2StepCount) / CGFloat(totalSteps) : 0

// 进度条主体
HStack(alignment: .center, spacing: 0) {
    // 用户1的进度条(左到右填充)
    Rectangle()
        .fill(Color(red: 0.965, green: 0.224, blue: 0.49))
        .frame(width: 110 * user1Progress, height: 11) // 总宽度设为110,对应原来两个55的总和
    // 用户2的进度条(右到左填充)
    Rectangle()
        .fill(Color(red: 0.208, green: 0.231, blue: 0.314))
        .frame(width: 110 * user2Progress, height: 11)
}
// 叠加步数文本
.overlay(
    HStack {
        Text(String(nowduelList.user1StepCount))
            .font(.system(size: 8))
            .bold()
            .foregroundColor(.white)
            .padding(.leading, 4)
        Spacer()
        Text(String(nowduelList.user2StepCount))
            .font(.system(size: 8))
            .bold()
            .foregroundColor(.white)
            .padding(.trailing, 4)
    }
)
.frame(width: 110, height: 11)
.cornerRadius(5.5) // 可选:给进度条加圆角,更美观

关键改动:

  • 移除trim,用frame(width:)根据进度比例控制填充宽度,这样进度从0开始就能正常显示。
  • 两个进度条放在同一个HStack里,实现左右拼接的交互效果。
  • 用overlay把文本放在进度条上方,分别对齐左右。
  • 增加总步数为0的边界处理,防止运行时错误。

如果需要固定总宽度为55,只需把代码里的110替换成55即可,进度计算逻辑不变。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 14:15:35