如何通过代码为UITableViewCell添加竖条及复用与实现优化问题
嘿,这个需求我刚好做过类似的,完全可以高效解决,不用搞复杂的多cell或者图片方案,给你梳理下思路和具体实现:
解决方案梳理
1. 完全可以复用同一个UITableViewCell动态配置竖条
复用是UITableView的核心优化点,绝对不需要为不同竖条数量/颜色创建多个cell类。你只需要给每个数据项绑定对应的竖条配置(比如颜色数组),在cellForRowAt回调里动态更新cell的竖条即可,完全不影响复用效率。
2. 不用创建多个自定义cell,同一cell适配多竖条场景
不管是1个、2个还是3个竖条,都可以在同一个自定义cell里处理。推荐预创建最大数量竖条视图的方式(你的场景最多3个):初始化时就创建好3个竖条UIView,默认隐藏,配置时根据数据显示对应数量的视图并设置颜色。这种方式避免了频繁创建销毁视图,性能最优,比动态添加移除视图更高效。
3. 用UIView替代UIImageView实现纯色竖条(性能拉满)
纯色竖条用UIView是最佳选择,系统渲染纯色UIView的开销远低于UIImageView——不用加载解码图片,内存占用也极小。直接给UIView设置backgroundColor就能实现,简单又高效。
具体代码示例
第一步:定义数据模型
先给每个列表项定义一个模型,包含标题和竖条颜色数组(数组长度对应竖条数量):
struct ListItem { let title: String let stripeColors: [UIColor] }
第二步:自定义UITableViewCell
创建一个自定义cell,内部处理竖条的布局和配置逻辑:
import UIKit class StripedTableViewCell: UITableViewCell { // 竖条宽度,可按需调整 private let stripeWidth: CGFloat = 4 // 预创建3个竖条视图(对应需求中最多3个的场景) private let stripeViews = [UIView(), UIView(), UIView()] override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { super.init(style: style, reuseIdentifier: reuseIdentifier) setupStripesLayout() } required init?(coder: NSCoder) { super.init(coder: coder) setupStripesLayout() } private func setupStripesLayout() { stripeViews.forEach { view in view.translatesAutoresizingMaskIntoConstraints = false view.isHidden = true contentView.addSubview(view) // 竖条垂直方向铺满cell NSLayoutConstraint.activate([ view.topAnchor.constraint(equalTo: contentView.topAnchor), view.bottomAnchor.constraint(equalTo: contentView.bottomAnchor), view.widthAnchor.constraint(equalToConstant: stripeWidth) ]) } // 第一个竖条贴cell左侧 NSLayoutConstraint.activate([ stripeViews[0].leadingAnchor.constraint(equalTo: contentView.leadingAnchor) ]) // 后续竖条依次紧挨着前一个 for i in 1..<stripeViews.count { NSLayoutConstraint.activate([ stripeViews[i].leadingAnchor.constraint(equalTo: stripeViews[i-1].trailingAnchor) ]) } } // 对外暴露的配置方法,根据模型更新内容和竖条 func configure(with item: ListItem) { textLabel?.text = item.title // 先隐藏所有竖条,避免复用残留 stripeViews.forEach { $0.isHidden = true } // 根据模型的颜色数组配置对应数量的竖条 for (index, color) in item.stripeColors.enumerated() { guard index < stripeViews.count else { break } // 防止数组越界 let stripeView = stripeViews[index] stripeView.backgroundColor = color stripeView.isHidden = false } } }
第三步:在ViewController中使用
class ViewController: UIViewController, UITableViewDataSource { private let tableView = UITableView() private let items: [ListItem] = [ ListItem(title: "Item A", stripeColors: [.systemRed]), ListItem(title: "Item B", stripeColors: [.systemBlue]), ListItem(title: "Item C", stripeColors: [.systemGreen]), ListItem(title: "Item D", stripeColors: [.systemRed, .systemYellow, .systemBlue]), ListItem(title: "Item E", stripeColors: [.systemPurple]), ListItem(title: "Item F", stripeColors: [.systemOrange, .systemGreen]), ListItem(title: "Item G", stripeColors: [.systemCyan, .systemMagenta]) ] override func viewDidLoad() { super.viewDidLoad() setupTableView() } private func setupTableView() { tableView.translatesAutoresizingMaskIntoConstraints = false view.addSubview(tableView) NSLayoutConstraint.activate([ tableView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor), tableView.leadingAnchor.constraint(equalTo: view.leadingAnchor), tableView.trailingAnchor.constraint(equalTo: view.trailingAnchor), tableView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor) ]) tableView.register(StripedTableViewCell.self, forCellReuseIdentifier: "StripedCell") tableView.dataSource = self } func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return items.count } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "StripedCell", for: indexPath) as! StripedTableViewCell cell.configure(with: items[indexPath.row]) return cell } }
额外优化建议
- 如果后续竖条数量可能超过3个,可以把预创建的数量改成可配置属性,或者在cell里动态维护竖条视图数组,但预创建固定最大数量的方式性能最优。
- 可以给竖条添加间距(比如在布局时设置trailing的偏移),让视觉效果更舒适。
- 所有布局操作都放在cell初始化时完成,
cellForRowAt里只做数据配置,保证列表滚动流畅。
内容的提问来源于stack exchange,提问作者wbk727
相关产品推荐
相关产品推荐

