UITableView自定义分割线显示为双线问题该如何解决?
实际异常效果:
期望实现效果:
异常原因
你已经在Storyboard中将UITableView的Separator设为None,系统原生分割线已经关闭,所以异常完全来自自定义分割线的逻辑错误:
- 分割线添加时机错误:你将分割线的创建、添加逻辑写在了
setSelected(_:animated:)方法中,该方法会在每次cell被选中/取消选中时触发,每触发一次就会新建一个分割线视图添加到contentView上,多个高度为1的视图堆叠后,视觉上就会呈现双线、粗线的异常效果。 - 布局逻辑错误:直接使用当前
bounds计算分割线frame,没有适配cell复用、尺寸变化的场景,容易出现分割线位置错位的问题。 - 拼写错误:代码中
@IBOutlet weak var transactionList: ransactionList!的类型名少了首字母T,属于笔误,需要修正。
修复方案
- 把分割线声明为cell的全局私有属性,全局仅创建一次,避免重复添加
- 将分割线的初始化、添加逻辑移到
awakeFromNib()方法中,仅在cell加载时执行一次 - 重写
layoutSubviews()方法,在cell布局更新时重新计算分割线的frame,保证位置始终正确 - 移除
setSelected(_:animated:)中所有和分割线相关的代码,该方法仅保留选中状态处理逻辑
修正后完整代码
class ListTableViewCell: UITableViewCell { // 声明为全局属性,仅创建一次 private let separator = UIView() // 修正原代码的拼写错误 @IBOutlet weak var transactionList: TransactionList! override func awakeFromNib() { super.awakeFromNib() // 分割线配置仅执行一次 separator.backgroundColor = .blue contentView.addSubview(separator) } override func layoutSubviews() { super.layoutSubviews() // 每次cell布局更新时重新计算分割线frame,适配尺寸变化 separator.frame = CGRect(x: 8, y: bounds.height - 0.5, width: bounds.width - 22, height: 1) } override func setSelected(_ selected: Bool, animated: Bool) { super.setSelected(selected, animated: animated) // 此处仅处理选中相关的业务逻辑 } }
如果希望避免手动计算frame的适配问题,也可以用自动布局实现分割线约束,稳定性更高:
override func awakeFromNib() { super.awakeFromNib() separator.backgroundColor = .blue separator.translatesAutoresizingMaskIntoConstraints = false contentView.addSubview(separator) NSLayoutConstraint.activate([ separator.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 8), separator.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -22), separator.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -0.5), separator.heightAnchor.constraint(equalToConstant: 1) ]) }
内容的提问来源于stack exchange,提问作者LgSus97
相关产品推荐
相关产品推荐

