在iOS/macOS开发中,TableView中的集合视图通常指的是在表格单元格(UITableViewCell)内嵌入集合视图(UICollectionView)的复合布局。这种设计模式常见于需要在一个表格行内展示多个可交互项目的场景。
首先需要在UITableViewCell中嵌入UICollectionView:
class CollectionTableViewCell: UITableViewCell {
var collectionView: UICollectionView!
override init(style: UITableViewCell.Ctyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
setupCollectionView()
}
func setupCollectionView() {
let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .horizontal
collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
collectionView.delegate = self
collectionView.dataSource = self
collectionView.register(CollectionCell.self, forCellWithReuseIdentifier: "CollectionCell")
contentView.addSubview(collectionView)
// 设置约束...
}
}
extension CollectionTableViewCell: UICollectionViewDelegate {
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
// 取消之前的选择
if let selectedIndexPath = collectionView.indexPathsForSelectedItems?.first {
collectionView.deselectItem(at: selectedIndexPath, animated: true)
}
// 处理新选择
collectionView.selectItem(at: indexPath, animated: true, scrollPosition: [])
print("Selected item at \(indexPath.row)")
}
}
extension CollectionTableViewCell: UICollectionViewDelegate {
func collectionView(_ collectionView: UICollectionView, shouldSelectItemAt indexPath: IndexPath) -> Bool {
if let selectedItems = collectionView.indexPathsForSelectedItems {
return selectedItems.count < 3 // 限制最多选择3个项目
}
return true
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
print("Selected item at \(indexPath.row)")
}
func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath) {
print("Deselected item at \(indexPath.row)")
}
}
class CollectionCell: UICollectionViewCell {
override var isSelected: Bool {
didSet {
backgroundColor = isSelected ? .systemBlue : .systemGray5
}
}
}
原因: 当表格视图滚动时,单元格会被重用,导致选择状态丢失。
解决方案: 在UITableViewCell中保存选择状态:
class CollectionTableViewCell: UITableViewCell {
var selectedIndexPaths = Set<IndexPath>()
// 在配置单元格时恢复选择状态
func configure(with selectedItems: Set<IndexPath>) {
self.selectedIndexPaths = selectedItems
selectedItems.forEach {
collectionView.selectItem(at: $0, animated: false, scrollPosition: [])
}
}
}
原因: UITableView和UICollectionView的选择事件可能互相干扰。
解决方案: 区分处理触摸事件:
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
let view = super.hitTest(point, with: event)
return view is UICollectionView ? view : nil
}
没有搜到相关的文章