UITableView滚动时图片重叠问题修复求助(附代码)
解决UITableView滚动时图片重叠的问题
这问题我太熟啦!你遇到的图片重叠本质是UITableViewCell复用机制在搞鬼——每次复用cell时你都往上面加新的UIImageView,旧的不会自动消失,滚来滚去就堆在一起了。给你两个靠谱的解决办法,优先推荐第一个(规范又省心):
方案一:自定义UITableViewCell(最佳实践)
自定义Cell能从根源解决复用带来的视图叠加问题,把UIImageView作为Cell的固定子视图,不用每次创建新的。
步骤1:创建自定义Cell类
import UIKit class ATMTableViewCell: UITableViewCell { // 声明银行图标视图作为Cell的属性 let bankIconImageView: UIImageView = { let imageView = UIImageView() imageView.layer.cornerRadius = 20 imageView.layer.masksToBounds = true imageView.contentMode = .scaleToFill imageView.translatesAutoresizingMaskIntoConstraints = false // 用AutoLayout需添加 return imageView }() override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { super.init(style: style, reuseIdentifier: reuseIdentifier) // 初始化时就把图标视图加到Cell的contentView上(比直接加cell更规范) contentView.addSubview(bankIconImageView) // 用AutoLayout设置布局(替换你原来的frame,适配不同屏幕) NSLayoutConstraint.activate([ bankIconImageView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -20), bankIconImageView.centerYAnchor.constraint(equalTo: contentView.centerYAnchor), bankIconImageView.widthAnchor.constraint(equalToConstant: 70), bankIconImageView.heightAnchor.constraint(equalToConstant: 70) ]) // 统一设置文本标签样式 textLabel?.textColor = .black textLabel?.font = UIFont.systemFont(ofSize: 13) } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } }
步骤2:修改tableView的cellForRow方法
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { // 强转成自定义Cell let cell = tableView.dequeueReusableCell(withIdentifier: "atmCell", for: indexPath) as! ATMTableViewCell let atm = AtmList.instance.atms[indexPath.row] cell.textLabel?.text = atm.title cell.detailTextLabel?.text = atm.subtitle // 直接给Cell的图标视图赋值图片,不用再创建新视图 cell.bankIconImageView.image = getBankImage(for: atm.title) return cell } // 把原来复杂的if-else抽成单独方法,代码更清晰 private func getBankImage(for bankTitle: String) -> UIImage? { // 用字典映射替代一堆if-else,维护起来更方便 let bankImageMap: [String: String] = [ "Wema": "wemaBank_pin", "Access": "AccessBank_pin", "Citi": "CitiBank_pin", "Diamond": "DiamondBank_pin", "Heritage": "HeritageBank_Pin", "Providus": "ProvidusBank_pin", "Fidelity": "FidelityBank_pin", "FCMB": "FCMB_pin", "Union": "UnionBank_pin", "GTBank": "GTBank_pin", "FirstBank": "FirstBank_pin", "Keystone": "KeystoneBank_pin", "Skye": "skyeBank_pin", "Eco": "ecoBank_pin", "Zenith": "ZenithBank_pin", "UBA": "UBA_pin", "Unity": "UnityBank_pin", "Stanbic": "St..." // 此处你原代码图片名未写完,自行补全 ] // 根据标题前缀匹配对应图片 for (key, imageName) in bankImageMap { if bankTitle.hasPrefix(key) { return UIImage(named: imageName) } } return nil // 无匹配时返回空 }
方案二:给UIImageView加Tag,复用现有视图(快速临时解决方案)
如果不想自定义Cell,也可以每次复用Cell时,先找有没有已存在的图标视图,有就复用,没有再创建:
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "atmCell", for: indexPath) let atm = AtmList.instance.atms[indexPath.row] cell.textLabel?.text = atm.title cell.textLabel?.textColor = .black cell.textLabel?.font = UIFont.systemFont(ofSize: 13) cell.detailTextLabel?.text = atm.subtitle // 定义固定Tag值,用于查找已存在的视图 let iconTag = 1001 var cellImage: UIImageView! // 优先复用已有视图 if let existingImageView = cell.viewWithTag(iconTag) as? UIImageView { cellImage = existingImageView } else { // 无视图时再创建并添加 cellImage = UIImageView(frame: CGRect(x: 290, y: 39, width: 70, height: 70)) cellImage.layer.cornerRadius = 20 cellImage.layer.masksToBounds = true cellImage.contentMode = .scaleToFill cellImage.tag = iconTag // 设置Tag,方便下次复用查找 cell.addSubview(cellImage) } // 图片匹配逻辑(可替换为上面的字典映射) if let firstChar = cell.textLabel?.text?.first { switch firstChar { case "W": cellImage.image = UIImage(named: "wemaBank_pin") case "A": cellImage.image = UIImage(named: "AccessBank_pin") case "C": cellImage.image = UIImage(named: "CitiBank_pin") // 剩余匹配逻辑自行补全... default: cellImage.image = nil } } return cell }
为啥原来的代码会重叠?
UITableView采用Cell复用池机制:当Cell滚出屏幕时会被放入复用池,下次需要时直接取出复用。你原来的代码每次调用cellForRowAt都新建一个UIImageView并执行addSubview,导致复用的Cell上叠加了N个UIImageView,滚动时就出现了图片重叠的情况。
内容的提问来源于stack exchange,提问作者Naza
相关产品推荐
相关产品推荐

