UICollectionView无法全屏、单行单单元格及FlowLayout布局警告问题求助
我来帮你拆解并搞定这两个头疼的问题:
问题1:UICollectionView无法铺满全屏
你写的collectionView约束完全搞反了!当前代码是让父view的边锚点对齐collectionView的边,这会导致collectionView的尺寸一直停留在初始的.zero状态,根本不可能铺满父view。
修正约束代码:
NSLayoutConstraint.activate([ collectionView.leadingAnchor.constraint(equalTo: view.leadingAnchor), collectionView.trailingAnchor.constraint(equalTo: view.trailingAnchor), collectionView.topAnchor.constraint(equalTo: view.topAnchor), collectionView.bottomAnchor.constraint(equalTo: view.bottomAnchor) ])
把约束的主体换成collectionView,让它的四边对齐父view的四边,这样才能真正铺满全屏。
问题2:持续出现的FlowLayout布局警告
警告的核心原因是初始布局阶段,collectionView的frame还没被约束更新为正确尺寸,此时你在sizeForItemAt里返回的CGSize(width: collectionView.frame.width, height: collectionView.frame.height)其实是(0,0)。而FlowLayout会严格检查item高度规则:
The item height must be less than the height of the UICollectionView minus the section insets top and bottom values, minus the content insets top and bottom values.
此时collectionView的frame高度是0,加上adjustedContentInset的上下值(44+34=78),计算出的允许最大高度是负数,0自然不满足小于负数的条件,所以触发警告。
解决方案:
方案1:改用collectionView的bounds+adjustedContentInset计算item大小
在sizeForItemAt里,用collectionView.bounds.size替代frame.size,同时考虑系统自动添加的content inset(比如导航栏、tabbar带来的偏移):
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { let availableWidth = collectionView.bounds.width - collectionView.adjustedContentInset.left - collectionView.adjustedContentInset.right let availableHeight = collectionView.bounds.height - collectionView.adjustedContentInset.top - collectionView.adjustedContentInset.bottom return CGSize(width: availableWidth, height: availableHeight) }
方案2:在布局完成后刷新collectionView布局
在viewDidLayoutSubviews里强制让布局重新计算,确保在frame正确后再生成item尺寸:
override func viewDidLayoutSubviews() { super.viewDidLayoutSubviews() collectionView.collectionViewLayout.invalidateLayout() }
方案3:调整contentInset调整行为(可选)
如果你的页面有导航栏,不想让系统自动添加额外的content inset,可以设置:
collectionView.contentInsetAdjustmentBehavior = .never
(注意:这会让collectionView内容顶到导航栏下方,如果你需要内容避开导航栏,优先用方案1的adjustedContentInset计算)
额外修复:ImageCollectionViewCell的约束
你的cell里imageView的约束也写反了!应该是让imageView的四边对齐cell的四边,而不是cell对齐imageView:
NSLayoutConstraint.activate([ imageView.leadingAnchor.constraint(equalTo: leadingAnchor), imageView.trailingAnchor.constraint(equalTo: trailingAnchor), imageView.topAnchor.constraint(equalTo: topAnchor), imageView.bottomAnchor.constraint(equalTo: bottomAnchor) ])
这个错误会导致图片无法铺满cell,修正后才能让图片显示全屏。
把这些调整都做完后,你的UICollectionView应该能正常铺满全屏,布局警告也会彻底消失。
内容的提问来源于stack exchange,提问作者Salman500

