如何避免Swift中不同UITableViewCell的label文字重叠显示
问题描述
UITableView滚动时cell上的UILabel出现文字内容重叠,对应有三张参考截图:文字标签重叠截图、label当前约束截图、完整视图层级截图。
现有相关代码
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { if let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as? ViewControllerTableViewCell { let immy = cell.viewWithTag(1) as? UIImageView let person: Userx = people[indexPath.row] let text = person.Education cell.lblName.text = person.Education ///key line cell.lblName.text = text?.uppercased() cell.lblName?.layer.masksToBounds = true let person5 = colorArray[indexPath.row] let person6 = colorArray1[indexPath.row] let person7 = colorArray2[indexPath.row] let like = cell.viewWithTag(3) as? UIButton cell.backgroundColor = person5 like?.backgroundColor = person6 immy?.backgroundColor = person7 cell.lblName.baselineAdjustment = .alignCenters cell.postID = self.people[indexPath.row].postID cell.row = indexPath.row cell.delegate = self cell.delegate2 = self DispatchQueue.main.asyncAfter(deadline: .now() + 2) { like?.isUserInteractionEnabled = true } return cell } return UITableViewCell() }
已尝试的解决方法
- 重写自定义cell的
prepareForReuse方法,设置lblName.text = ""以及lblName.text = nil,未生效 - 在
cellForRowAt方法中先清空label内容再赋值,逻辑如下,未生效
cell.lblName.text = nil if cell.lblName.text == nil{ cell.lblName.text = person.Education }
- 调整label约束,未生效
猜测触发场景
- 从TableViewController场景切换到内嵌UITableView的ViewController场景后首次出现
- 给cell设置不同背景色后首次出现
解决方案
- 排查重复label问题:打开Xcode视图层级调试工具,查看文字重叠位置是否存在多个UILabel实例,若存在,删除xib/Storyboard或代码中重复添加的多余label即可。
- 修正
cellForRowAt逻辑,移除冗余赋值,增加复用校验:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { guard let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as? ViewControllerTableViewCell else { return UITableViewCell() } // 复用前统一清空所有可修改控件内容 cell.lblName.text = nil cell.lblName.attributedText = nil (cell.viewWithTag(1) as? UIImageView)?.image = nil (cell.viewWithTag(3) as? UIButton)?.isUserInteractionEnabled = false let person: Userx = people[indexPath.row] cell.lblName.text = person.Education?.uppercased() cell.lblName.layer.masksToBounds = true let immy = cell.viewWithTag(1) as? UIImageView let like = cell.viewWithTag(3) as? UIButton cell.backgroundColor = colorArray[indexPath.row] // 给label设置和cell一致的不透明背景,避免旧文字透出 cell.lblName.backgroundColor = cell.backgroundColor like?.backgroundColor = colorArray1[indexPath.row] immy?.backgroundColor = colorArray2[indexPath.row] cell.lblName.baselineAdjustment = .alignCenters cell.postID = person.postID cell.row = indexPath.row cell.delegate = self cell.delegate2 = self // 延迟操作增加复用校验,避免cell已滚出屏幕后还执行旧任务 DispatchQueue.main.asyncAfter(deadline: .now() + 2) { [weak tableView, weak cell] in guard let cell = cell, let currentIndexPath = tableView?.indexPath(for: cell), currentIndexPath == indexPath else { return } like?.isUserInteractionEnabled = true } return cell }
- 完善自定义cell的复用重置逻辑,在
ViewControllerTableViewCell类中重写prepareForReuse:
override func prepareForReuse() { super.prepareForReuse() lblName.text = nil lblName.attributedText = nil (viewWithTag(1) as? UIImageView)?.image = nil (viewWithTag(3) as? UIButton)?.isUserInteractionEnabled = false }
内容的提问来源于stack exchange,提问作者florida27
相关产品推荐
相关产品推荐

