You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何避免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设置不同背景色后首次出现

解决方案
  1. 排查重复label问题:打开Xcode视图层级调试工具,查看文字重叠位置是否存在多个UILabel实例,若存在,删除xib/Storyboard或代码中重复添加的多余label即可。
  2. 修正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
}
  1. 完善自定义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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 06:48:03