TableViewCell中ProgressView自定义颜色时无法正常更新的问题
问题解决:自定义颜色下UIProgressView进度渲染异常
问题原因
这个异常是由于UIProgressView的渲染逻辑导致的:当使用自定义UIColor时,如果先设置进度值再设置颜色,控件无法正确渲染低于阈值的进度;而系统预定义颜色(如UIColor.red)是系统优化过的颜色对象,不会触发这个渲染bug。
解决方案
1. 调整设置顺序
将progressViewStyle、progressTintColor的设置放在progress值之前,确保控件先完成样式和颜色的初始化,再渲染进度:
2. 复用自定义颜色对象
避免在cellForRowAt中每次创建新的UIColor实例,减少不必要的对象创建,同时规避渲染异常。
修改后的代码
import UIKit class ViewController: UITableViewController { var time = 0 var progressNumber:Float = 0.2 let dummyArray = ["Pull Up","IOS","Strecthing","Bench Press"] // 提前创建自定义颜色,复用对象 let customProgressColor = UIColor(red: 0.3, green: 0.3, blue: 0.3, alpha: 1) override func viewDidLoad() { super.viewDidLoad() tableView.register(UINib(nibName: "progreeCell", bundle: nil), forCellReuseIdentifier: "CustomCell") tableView.rowHeight = 60 Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(updateTime), userInfo: nil, repeats: true) } @objc func updateTime() { progressNumber += 0.1 DispatchQueue.main.async { self.tableView.reloadData() } } override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { progressNumber += 0.03 tableView.reloadData() } override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return dummyArray.count } override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "CustomCell", for: indexPath) as! progreeCell cell.textLabel?.text = dummyArray[indexPath.row] // 调整顺序:样式 → 颜色 → 进度 cell.progressBar.progressViewStyle = .bar cell.progressBar.progressTintColor = customProgressColor cell.progressBar.alpha = 0.5 cell.progressBar.progress = progressNumber / Float(indexPath.row + 1) return cell } }
补充:十六进制转颜色的正确方法
如果使用十六进制生成自定义颜色,确保转换方法生成标准sRGB空间的颜色,示例如下:
extension UIColor { convenience init(hex: String, alpha: CGFloat = 1.0) { var hexSanitized = hex.trimmingCharacters(in: .whitespacesAndNewlines) hexSanitized = hexSanitized.replacingOccurrences(of: "#", with: "") var rgb: UInt64 = 0 Scanner(string: hexSanitized).scanHexInt64(&rgb) let red = CGFloat((rgb & 0xFF0000) >> 16) / 255.0 let green = CGFloat((rgb & 0x00FF00) >> 8) / 255.0 let blue = CGFloat(rgb & 0x0000FF) / 255.0 self.init(red: red, green: green, blue: blue, alpha: alpha) } }
内容的提问来源于stack exchange,提问作者Bravo
相关产品推荐
相关产品推荐

