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

代码设置ProgressView的progressTint导致进度条尺寸异常

UIProgressView in UITableViewCell Shows Incorrect Progress Width After Setting progressTintColor

我最近也碰到过类似的坑,结合你描述的现象和代码,这大概率是UITableViewCell复用机制下,UIProgressView的状态残留+绘制顺序冲突导致的问题。先帮你拆解清楚,再给可行的解决方案:

问题核心分析

你的代码逻辑是先设置进度值,再修改progressTintColor——但UIProgressView在修改颜色时会触发重绘,而Cell复用后,ProgressView可能残留了上一次的状态(比如之前承载过进度100%的红色条)。这种情况下,重绘时会错误沿用旧的进度布局缓存,导致填充宽度计算偏差。前两个Cell受影响最明显,是因为它们是最先被创建和复用的,大概率承载过满进度的Cell,残留状态更顽固。

解决方案1:调整属性设置顺序(先设颜色再设进度)

把颜色设置放在进度赋值前面,让UIProgressView先明确要使用的颜色,再计算并绘制对应的进度宽度:

let max: Double = MyGroup!.EndTimeSeconds - MyGroup!.StartTimeSeconds
let progress: Double = Date().timeIntervalSince1970 - MyGroup!.StartTimeSeconds

// 先重置轨道颜色(可选但更稳妥,避免复用残留)
Cell.ProgressView.trackTintColor = UIColor.pts_lightgrey

if max >= progress {
    // 设置标签颜色
    Cell.DescriptionLabel.textColor = .black
    Cell.SubtitleLabel.textColor = .black
    Cell.TargetDeliveryTimeLabel.textColor = .pts_darkergrey
    
    // 先设置进度条颜色
    if max * 0.75 <= progress {
        Cell.ProgressView.progressTintColor = .pts_pbamber
    } else {
        Cell.ProgressView.progressTintColor = .pts_green
    }
    // 再设置进度值(无需重复赋值progress,setProgress已处理)
    let progressValue = Float(progress / max)
    Cell.ProgressView.setProgress(progressValue, animated: false)
} else {
    // 设置标签颜色
    Cell.DescriptionLabel.textColor = .white
    Cell.SubtitleLabel.textColor = .white
    Cell.TargetDeliveryTimeLabel.textColor = .white
    
    // 先设颜色
    Cell.ProgressView.progressTintColor = .pts_pbred
    // 再设进度
    Cell.ProgressView.setProgress(1, animated: false)
}

// 圆角设置放在最后不影响
Cell.ProgressView.layer.cornerRadius = 4
Cell.ProgressView.clipsToBounds = true

解决方案2:在Cell复用前彻底重置状态

为了从根源避免复用残留,建议在自定义Cell类中重写prepareForReuse()方法,重置所有关键属性:

class YourCustomCell: UITableViewCell {
    // 你的IBOutlet定义...
    
    override func prepareForReuse() {
        super.prepareForReuse()
        // 重置进度条状态
        ProgressView.progress = 0
        ProgressView.progressTintColor = .clear
        ProgressView.trackTintColor = .pts_lightgrey
        // 同时重置标签颜色,避免文字颜色残留
        DescriptionLabel.textColor = .black
        SubtitleLabel.textColor = .black
        TargetDeliveryTimeLabel.textColor = .pts_darkergrey
    }
}

额外优化点

你当前代码里同时调用了setProgress(_:animated:)和直接赋值progress,这两个操作是重复的——setProgress内部已经会更新progress属性,保留其中一个即可(推荐用setProgress,它会正确处理绘制逻辑)。

按照上面的方法调整后,进度条的显示应该会和计算值完全匹配,颜色切换也不会再干扰进度宽度了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 20:17:44