Swift中点击按钮切换UICollectionView单元格为列表布局的实现方案
UICollectionView 切换网格/列表布局实现方案
问题描述
页面中存在一个UICollectionView,点击高亮的View按钮后,需要将原有的单元格布局切换为类UITableView的列表样式。
原布局效果:
目标布局效果:
实现步骤
- 首先定义布局状态枚举,用于标记当前展示样式
enum DisplayStyle { case grid case list } // 声明当前布局状态的成员变量 var currentStyle: DisplayStyle = .grid
- 分别实现两种布局的构建方法,推荐使用
UICollectionViewCompositionalLayout实现,适配更灵活
// 构建网格布局(示例为2列网格) private func makeGridLayout() -> UICollectionViewLayout { let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(0.5), heightDimension: .fractionalHeight(1.0)) let item = NSCollectionLayoutItem(layoutSize: itemSize) item.contentInsets = NSDirectionalEdgeInsets(top: 8, leading: 8, bottom: 8, trailing: 8) let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .absolute(180)) let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, subitems: [item]) let section = NSCollectionLayoutSection(group: group) section.contentInsets = NSDirectionalEdgeInsets(top: 8, leading: 8, bottom: 8, trailing: 8) return UICollectionViewCompositionalLayout(section: section) } // 构建列表布局(类UITableView单栏样式) private func makeListLayout() -> UICollectionViewLayout { // iOS 14 及以上可以直接用系统自带的列表配置,更贴近UITableView效果 if #available(iOS 14.0, *) { return UICollectionViewCompositionalLayout.list(using: .plain) } else { // 低版本手动实现列表布局 let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .absolute(60)) let item = NSCollectionLayoutItem(layoutSize: itemSize) let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .absolute(60)) let group = NSCollectionLayoutGroup.vertical(layoutSize: groupSize, subitems: [item]) let section = NSCollectionLayoutSection(group: group) return UICollectionViewCompositionalLayout(section: section) } }
- 按钮点击时切换布局,同时更新cell渲染逻辑
@IBAction func viewSwitchButtonTapped(_ sender: UIButton) { // 切换布局状态 currentStyle = currentStyle == .grid ? .list : .grid // 获取目标布局 let targetLayout = currentStyle == .grid ? makeGridLayout() : makeListLayout() // 带动画切换布局,不需要动画可以将animated参数设为false collectionView.setCollectionViewLayout(targetLayout, animated: true) // 若两种布局的cell样式存在差异,需要刷新集合视图重新渲染cell collectionView.reloadData() }
- 在
collectionView(_:cellForItemAt:)方法中根据当前currentStyle的取值,调整cell的UI样式、出列对应类型的cell即可。
如果使用旧版
UICollectionViewFlowLayout实现,只需要在点击按钮时修改对应的itemSize、minimumInteritemSpacing、minimumLineSpacing等属性,调用collectionView.reloadData()即可生效。
内容的提问来源于stack exchange,提问作者Ahmed Ayoub
相关产品推荐
相关产品推荐

