Swift类中无Storyboard编程实现带自定义单元格的UICollectionView
纯代码实现带自定义标签单元格的UICollectionView(Swift)
我来帮你完善这个纯代码创建UICollectionView的实现,确保能正常显示带标签的自定义单元格,下面是完整的可运行代码和关键步骤解析:
完整实现代码
首先我们需要创建一个自定义UICollectionViewCell,把标签封装在单元格内部(避免复用混乱),再实现承载CollectionView的BoardView:
import UIKit // 自定义带标签的CollectionView单元格 class CustomCollectionViewCell: UICollectionViewCell { // 单元格内的标签 let cellLabel: UILabel = { let label = UILabel() label.textAlignment = .center label.font = UIFont.systemFont(ofSize: 16) label.translatesAutoresizingMaskIntoConstraints = false // 关闭自动布局转换 return label }() override init(frame: CGRect) { super.init(frame: frame) setupCellUI() } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") // 纯代码实现无需支持Storyboard/XIB } private func setupCellUI() { // 把标签添加到单元格的contentView(必须用contentView,不能直接加在cell上) contentView.addSubview(cellLabel) // 设置标签的AutoLayout约束 NSLayoutConstraint.activate([ cellLabel.centerXAnchor.constraint(equalTo: contentView.centerXAnchor), cellLabel.centerYAnchor.constraint(equalTo: contentView.centerYAnchor), cellLabel.leadingAnchor.constraint(greaterThanOrEqualTo: contentView.leadingAnchor, constant: 8), cellLabel.trailingAnchor.constraint(lessThanOrEqualTo: contentView.trailingAnchor, constant: -8) ]) // 给单元格加一点样式 contentView.backgroundColor = .lightGray contentView.layer.cornerRadius = 8 } } // 承载CollectionView的自定义View class BoardView: UIView, UICollectionViewDataSource, UICollectionViewDelegate { var boardTable: UICollectionView! let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout() var items = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"] // 测试数据 // 便利初始化方法 convenience init(frame: CGRect, title: String) { self.init(frame: frame) // 如果需要用title做额外操作(比如设置视图标题),可以在这里添加逻辑 } override init(frame: CGRect) { super.init(frame: frame) setupCollectionView() } required init?(coder: NSCoder) { super.init(coder: coder) setupCollectionView() } private func setupCollectionView() { // 1. 配置CollectionView布局 layout.scrollDirection = .vertical // 垂直滚动 layout.itemSize = CGSize(width: 80, height: 80) // 单元格大小 layout.minimumInteritemSpacing = 10 // 单元格水平间距 layout.minimumLineSpacing = 10 // 单元格垂直间距 layout.sectionInset = UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10) // 整体内边距 // 2. 初始化CollectionView boardTable = UICollectionView(frame: self.bounds, collectionViewLayout: layout) boardTable.translatesAutoresizingMaskIntoConstraints = false boardTable.dataSource = self boardTable.delegate = self boardTable.backgroundColor = .white // 3. 注册自定义单元格(必须注册,否则无法复用) boardTable.register(CustomCollectionViewCell.self, forCellWithReuseIdentifier: "CustomCell") // 4. 添加到父视图并设置约束(让CollectionView铺满整个BoardView) self.addSubview(boardTable) NSLayoutConstraint.activate([ boardTable.topAnchor.constraint(equalTo: self.topAnchor), boardTable.leadingAnchor.constraint(equalTo: self.leadingAnchor), boardTable.trailingAnchor.constraint(equalTo: self.trailingAnchor), boardTable.bottomAnchor.constraint(equalTo: self.bottomAnchor) ]) } // MARK: - UICollectionViewDataSource 数据源方法 func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return items.count // 返回数据总数 } func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { // 复用单元格并强转为自定义类型 let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CustomCell", for: indexPath) as! CustomCollectionViewCell // 给单元格的标签赋值 cell.cellLabel.text = items[indexPath.item] return cell } // MARK: - UICollectionViewDelegate 可选代理方法(点击事件) func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { print("点击了第\(indexPath.item + 1)个单元格,内容:\(items[indexPath.item])") } }
关键要点说明
- 自定义单元格的必要性:把UILabel封装在单元格内部,而不是放在BoardView中,这样每个单元格都有独立的标签,避免复用时出现内容混乱的问题。
- 布局配置:通过
UICollectionViewFlowLayout可以灵活控制单元格的大小、间距、滚动方向,适配不同的UI需求。 - AutoLayout约束:所有视图都关闭了
translatesAutoresizingMaskIntoConstraints,使用代码约束确保在不同屏幕尺寸下都能正常显示。 - 单元格注册与复用:必须先注册自定义单元格类,再通过
dequeueReusableCell复用,这是CollectionView性能优化的核心。
内容的提问来源于stack exchange,提问作者JoLight
相关产品推荐
相关产品推荐

