UICollectionView sizeForItemAt 调用但大小不正确
Posted
技术标签:
【中文标题】UICollectionView sizeForItemAt 调用但大小不正确【英文标题】:UICollectionView sizeForItemAt Called But Not Sized Correctly 【发布时间】:2019-10-08 17:02:02 【问题描述】:我希望第一个部分的单元格是集合视图的全宽,第二个部分是宽度的一半。启动时,单元格不尊重给定的宽度,尽管似乎尊重了高度。几秒钟后,collection view 被重新加载,并且大部分时间它将单元格设置为正确的大小。当手机的方向变为横向时,单元格会再次以不正确的大小绘制。
我尝试使用 UICollectionViewDelegateFlowLayout 和 sizeForItemAt 委托函数来设置单元格大小,但即使调用了该函数,它们也不遵循给定的大小。
目前,我正在设置部分插图,然后计算集合视图边界中单元格的剩余可用宽度,然后将宽度除以每行的单元格数。
class HomeCollectionViewController: UICollectionViewController, UICollectionViewDelegateFlowLayout
let sectionInsets = UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10)
override func viewDidLoad()
super.viewDidLoad()
self.collectionView?.contentInsetAdjustmentBehavior = .always
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize
return CGSize(width: collectionView.frame.width, height: 44)
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets
return self.sectionInsets
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat
return self.sectionInsets.left
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat
return 0
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize
var numberOfItemsPerRow: CGFloat = 1
var height: CGFloat = 0
switch indexPath.section
case 0:
numberOfItemsPerRow = 1
height = 97
case 1:
numberOfItemsPerRow = 2
height = 126
default:
break
let padding = self.sectionInsets.left * (numberOfItemsPerRow + 1)
let availableWidth = collectionView.bounds.size.width - padding
let width = availableWidth / numberOfItemsPerRow
return CGSize(width: width, height: height)
这会导致单元格大小不正确,如下图所示。 Incorrect Example Image
只有在重新加载集合视图之后才能正确调整它们的大小。 Correct Example Image
此外,当手机转为横向时,它的显示不正确。 Incorrect Landscape Example Image
要结束我的问题,第一部分的单元格应始终占可用宽度的 100%。如果可能的话,如果他们有一个自动高度,那将是非常好的。我试过使用 UICollectionViewFlowLayout.automaticSize.height 但我认为这行不通。对于第二部分,它需要始终占据可用宽度的 50%。
【问题讨论】:
【参考方案1】:如果您使用 Storyboard 创建 CollectionView。
我以为我必须invalidateLayout()
。事实证明,ios 13 存在一个奇怪的错误。
您必须创建自己的 UICollectionViewFlowLayout。在您的viewDidLoad()
中调用类似的内容
collectionView.collectionViewLayout =
let flowLayout = UICollectionViewFlowLayout()
flowLayout.scrollDirection = .horizontal
return flowLayout
()
【讨论】:
你的意思是 iOS 13,对吧? ;) 但是,是的,我的控制台 UICollectionViewFlowLayoutBreakForInvalidSizes 警告这样做了。 没什么大不了的,很清楚是什么意思。刚刚为其他阅读线程提供了反馈。干杯。【参考方案2】:您必须使 viewDidLayoutSubviews
上的布局无效才能重新计算单元格的大小。
我附上了代码sn-p。试试这个
override func viewDidLayoutSubviews()
super.viewDidLayoutSubviews()
collectionView.collectionViewLayout.invalidateLayout()
【讨论】:
在 iOS 13.1 上将其添加到我的UICollectionViewController
时导致无限循环。
它为我完成了工作。必须将其粘贴到扩展类中以上是关于UICollectionView sizeForItemAt 调用但大小不正确的主要内容,如果未能解决你的问题,请参考以下文章
如何滚动另一个 UICollectionView 下方的 UICollectionView?
UICollectionView 单元内部已加载,但 UICollectionView 未显示
UICollectionView 断言失败 -[UICollectionView _updateWithItems:tentativelyForReordering:]
UITableviewCell 中的 UICollectionView。添加约束后,UICollectionView 不显示