UITableView添加虚线底部分隔线无显示效果问题求助
解决UITableViewCell虚线底部分隔线不显示的问题
我之前也踩过这个坑!你的代码里有几个关键问题导致虚线没显示出来,咱们一步步修正:
问题分析
- cell的frame在
cellForRowAt中未确定:UITableView会在cellForRowAt之后才完成cell的布局计算,这时候cell.frame.size拿到的是初始默认值(比如44高度),不是最终布局后的尺寸,导致虚线的宽度或位置错误。 - 无效的绘制路径:你用了高度为0的
roundedRect来创建路径,这样的路径实际上是不存在的,自然画不出任何线条。 - 重复添加Layer的隐患:每次复用cell都会添加新的CAShapeLayer,不仅内存浪费,还可能导致显示混乱。
最佳解决方案:自定义UITableViewCell子类
推荐把虚线绘制逻辑放到cell子类的layoutSubviews方法中,这里能确保cell的布局已经完成,尺寸准确:
class CustomDashedCell: UITableViewCell { // 把虚线Layer作为cell的属性,避免重复创建 private let dashedBottomLayer = CAShapeLayer() override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { super.init(style: style, reuseIdentifier: reuseIdentifier) setupDashedLayer() } required init?(coder: NSCoder) { super.init(coder: coder) setupDashedLayer() } private func setupDashedLayer() { dashedBottomLayer.strokeColor = UIColor.black.cgColor dashedBottomLayer.fillColor = UIColor.clear.cgColor dashedBottomLayer.lineWidth = 2.0 dashedBottomLayer.lineJoin = .round dashedBottomLayer.lineDashPattern = [9, 6] layer.addSublayer(dashedBottomLayer) } override func layoutSubviews() { super.layoutSubviews() // 布局完成后更新虚线路径 let path = UIBezierPath() // 让线条居中在cell底部,y坐标减去线条宽度的一半 let bottomY = bounds.height - dashedBottomLayer.lineWidth / 2 path.move(to: CGPoint(x: 0, y: bottomY)) path.addLine(to: CGPoint(x: bounds.width, y: bottomY)) dashedBottomLayer.path = path.cgPath } }
如果你不想用子类的替代方案
如果暂时不想自定义cell,也可以修改你的原方法,注意先让cell完成布局,并且避免重复添加Layer:
func addDashedBottomBorder(to cell: UITableViewCell) { // 强制cell完成当前布局,确保bounds准确 cell.layoutIfNeeded() let color = UIColor.black.cgColor let shapeLayer = CAShapeLayer() shapeLayer.strokeColor = color shapeLayer.fillColor = UIColor.clear.cgColor shapeLayer.lineWidth = 2.0 shapeLayer.lineJoin = .round shapeLayer.lineDashPattern = [9, 6] shapeLayer.name = "DashedBottomBorder" // 给Layer命名,方便复用的时候移除 // 绘制底部直线路径 let bottomY = cell.bounds.height - shapeLayer.lineWidth / 2 let path = UIBezierPath() path.move(to: CGPoint(x: 0, y: bottomY)) path.addLine(to: CGPoint(x: cell.bounds.width, y: bottomY)) shapeLayer.path = path.cgPath // 移除cell上已有的虚线Layer,防止复用重复添加 cell.layer.sublayers?.filter { $0.name == "DashedBottomBorder" }.forEach { $0.removeFromSuperlayer() } cell.layer.addSublayer(shapeLayer) }
额外注意事项
- 如果你的UITableView用了自动高度(
UITableView.automaticDimension),一定要确保cell的布局约束完整,这样layoutSubviews或layoutIfNeeded才能拿到正确的高度。 - 可以根据需求调整
lineDashPattern的数组值,第一个数是虚线长度,第二个是间隔长度。
内容的提问来源于stack exchange,提问作者Jhony
相关产品推荐
相关产品推荐

