代码设置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
相关产品推荐
相关产品推荐

