Swift 5、Xcode中如何为UICollectionView的行添加下划线以分隔行?
嘿,这个需求在UICollectionView开发里挺常见的,我给你分享几种在Swift 5 + Xcode环境下实现每行下划线的方法,你可以根据自己的布局场景来选:
方法一:自定义Cell时添加底部下划线(适合每行单个Cell的场景)
这种方法最简单直接,就是在你自定义的UICollectionViewCell里,直接加一个UIView作为下划线,通过AutoLayout固定在Cell底部。
步骤和代码示例:
- 创建自定义Cell类,内部添加下划线视图并设置约束:
class CustomCollectionCell: UICollectionViewCell { // 下划线视图,可自定义颜色和厚度 private let underlineView: UIView = { let view = UIView() view.backgroundColor = .lightGray view.translatesAutoresizingMaskIntoConstraints = false return view }() override init(frame: CGRect) { super.init(frame: frame) setupSubviews() } required init?(coder: NSCoder) { super.init(coder: coder) setupSubviews() } private func setupSubviews() { contentView.addSubview(underlineView) // 用AutoLayout把下划线固定在Cell底部,左右对齐,高度设为1 NSLayoutConstraint.activate([ underlineView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor), underlineView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor), underlineView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor), underlineView.heightAnchor.constraint(equalToConstant: 1.0) ]) } }
- 在你的ViewController里注册这个自定义Cell,之后每个Cell底部都会有一条下划线啦。
方法二:用装饰视图添加整行贯穿的下划线(适合每行多个Cell的场景)
如果你的UICollectionView每行有多个Cell,想要一条贯穿整行的下划线,那用UICollectionView的装饰视图(Decoration View)是最合适的,它能独立于Cell生成整行的线条。
步骤1:自定义装饰视图
这就是个简单的UIView,用来作为下划线:
class UnderlineDecorationView: UICollectionReusableView { override init(frame: CGRect) { super.init(frame: frame) backgroundColor = .lightGray // 下划线颜色 } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } }
步骤2:自定义FlowLayout
我们需要重写FlowLayout的方法,计算每行的位置,然后给每行添加装饰视图的布局属性:
class UnderlineFlowLayout: UICollectionViewFlowLayout { // 定义装饰视图的标识 static let underlineKind = "UnderlineDecoration" override init() { super.init() // 注册装饰视图 register(UnderlineDecorationView.self, forDecorationViewOfKind: Self.underlineKind) } required init?(coder: NSCoder) { super.init(coder: coder) register(UnderlineDecorationView.self, forDecorationViewOfKind: Self.underlineKind) } override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? { guard let originalAttrs = super.layoutAttributesForElements(in: rect) else { return nil } var allAttrs = originalAttrs var lastRowY: CGFloat = -1 // 遍历所有Cell的布局属性,找出每行的起始位置 for attr in originalAttrs where attr.representedElementCategory == .cell { let currentRowY = attr.frame.minY if currentRowY != lastRowY { lastRowY = currentRowY // 创建下划线的布局属性 let underlineAttr = UICollectionViewLayoutAttributes( forDecorationViewOfKind: Self.underlineKind, with: attr.indexPath ) // 计算下划线的frame:宽度和CollectionView一致,高度1,位于该行Cell的底部 let underlineFrame = CGRect( x: 0, y: attr.frame.maxY, width: collectionView?.bounds.width ?? 0, height: 1.0 ) underlineAttr.frame = underlineFrame allAttrs.append(underlineAttr) } } return allAttrs } }
步骤3:在ViewController中使用自定义FlowLayout
class YourViewController: UIViewController, UICollectionViewDataSource { private var collectionView: UICollectionView! override func viewDidLoad() { super.viewDidLoad() setupCollectionView() } private func setupCollectionView() { // 使用我们自定义的FlowLayout let layout = UnderlineFlowLayout() layout.itemSize = CGSize(width: 120, height: 90) // 自定义Cell大小 layout.minimumLineSpacing = 0 // 行间距设为0,让下划线紧贴Cell底部 collectionView = UICollectionView(frame: view.bounds, collectionViewLayout: layout) collectionView.dataSource = self collectionView.register(UICollectionViewCell.self, forCellWithReuseIdentifier: "Cell") collectionView.backgroundColor = .white view.addSubview(collectionView) } // 实现DataSource方法 func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return 20 } func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) cell.backgroundColor = .systemBlue return cell } }
一些额外的小提示
- 下划线的颜色、厚度都可以根据你的UI设计调整,比如把
heightAnchor的值改成0.5会更细腻,颜色用UIColor(white: 0.9, alpha: 1)会更柔和。 - 如果你的CollectionView有contentInset,记得调整下划线的x坐标,比如把
x: 0改成collectionView!.contentInset.left,避免线条和屏幕边缘不对齐。 - 要是用方法二,记得把行间距
minimumLineSpacing设为0,不然下划线和Cell之间会有空隙。
内容的提问来源于stack exchange,提问作者Rizwan Ahmed
相关产品推荐
相关产品推荐

