如何用Collection View编写适配全屏幕的2列网格布局代码?
适配全屏幕的2列N行CollectionView网格解决方案
你的问题主要出在Section数量设置错误和Item尺寸计算未考虑完整布局参数上,导致不同屏幕尺寸下布局错乱。下面给你调整后的完整方案,保证2列布局适配所有设备:
核心修改点
- 把Section数量改为1:你要的是N行2列的单网格,不需要多Section
- 正确计算Item尺寸:将左右内边距(inset)、列间距(minimumInteritemSpacing)都纳入计算,避免元素超出屏幕
- 动态设置Item总数:根据你的数据数组长度返回
numberOfItemsInSection,自动生成对应行数
修改后的完整代码
// 替换成你的实际数据数组,用来控制Item总数 var dataArray: [Any] = [] // 1. 单Section即可实现N行2列布局 public func numberOfSections(in collectionView: UICollectionView) -> Int { return 1 } // 2. 根据数据总数动态生成Item数量,自动适配N行 public func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return dataArray.count } public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) if let cell1 = cell as? CollectionViewCell { // 这里可以给cell绑定数据,比如 cell1.titleLabel.text = dataArray[indexPath.item] as? String return cell1 } return cell } // 3. 精准计算Item尺寸,适配所有屏幕 func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { guard let layout = collectionViewLayout as? UICollectionViewFlowLayout else { return CGSize.zero } // 计算总占用的边距和间距:左右内边距总和 + 列间距(2列只有1个间距) let totalEdgeSpace = layout.sectionInset.left + layout.sectionInset.right let totalSpacing = layout.minimumInteritemSpacing * CGFloat(2 - 1) // 可用宽度 = 容器宽度 - 总边距 - 总间距,再平分给2个Item let availableWidth = collectionView.bounds.width - totalEdgeSpace - totalSpacing let itemWidth = availableWidth / 2 // 保持你原来的高度逻辑:宽度+15,也可以改成固定值或比例值 let itemHeight = itemWidth + 15 return CGSize(width: itemWidth, height: itemHeight) } public func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int ) -> UIEdgeInsets { return UIEdgeInsets(top: 5, left: 5, bottom: 5, right: 5) } public func collectionView( _ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { // 这里添加Item点击逻辑 } public func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat { return 5 // 控制上下Item的行间距 } public func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat { return 5 // 控制左右Item的列间距 }
额外优化建议
- 在
viewDidLayoutSubviews中调用collectionView.collectionViewLayout.invalidateLayout(),确保屏幕旋转或布局变化时,Item尺寸能重新计算适配 - 如果你的项目支持iOS 13+,可以考虑使用
UICollectionViewCompositionalLayout,代码会更简洁易维护
内容的提问来源于stack exchange,提问作者user3113946
相关产品推荐
相关产品推荐

