UICollectionView没有加载所有可见的单元格。

huangapple go评论52阅读模式
英文:

UICollectionView does not load all visible cells

问题

我有一个带有一些标头和(不同大小的)单元格的UICollectionView。我遇到的问题是,它似乎没有加载所有所需的单元格以填充可见区域,而是在我滚动一点后仅加载最新的一个:

如果我删除标头,问题就消失了,这让我怀疑我的collectionView(_:layout:referenceSizeForHeaderInSection:)方法可能是罪魁祸首,但即使我返回一个固定大小,问题仍然存在。

有人可以帮助我理解这里发生了什么吗?这里是一个带有这个问题的演示项目。

UICollectionView没有加载所有可见的单元格。

英文:

I have a UICollectionView with some headers and (various-sized) cells. The issue I got with it's that it looks like it doesn't load all the required cells to fill the visible area, but instead it only loads the latest one after I scroll a bit:

UICollectionView没有加载所有可见的单元格。

If I remove the headers the issue is gone, which made me suspect that my collectionView(_:layout:referenceSizeForHeaderInSection:) method to be at culprit, but even if I return a fixed size it still exhibits the same issue.

Can someone help me understand what's happening here? Here is a demo project with the issue, if someone is interested.

答案1

得分: 2

使用这一行代码:

flowLayout.estimatedItemSize = UICollectionViewFlowLayout.automaticSize

你没有为 Flow Layout 提供关于项目大小的任何提示。

因此,Flow Layout 基本上表示:

  • 我需要另一行单元格
  • 单元格的宽度可能与集合视图一样宽
  • 所以,只请求一个单元格

当你开始滚动时,当前可见的单元格已经定义了宽度,所以 Flow Layout 会请求另一个单元格。

你可以要么提供实际的估计项目大小,要么在 viewDidAppear() 中进行重写并在那里设置它:

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    if let fl = collectionView.collectionViewLayout as? UICollectionViewFlowLayout {
        // 让我们使用宽度的估计值为 40%,这样我们知道每行可以容纳 2 个单元格
        // 对于高度,使用一个合理的值
        fl.estimatedItemSize = .init(width: collectionView.frame.width * 0.4, height: 280.0)
    }
}

编辑

正如你在评论中所述,这还不够完美。

经过一些实验,将 0.4 更改为 0.2(这似乎很愚蠢,但...)似乎可以解决问题。

不过需要注意的是:

根据我的经验,如果我们设置以下属性,管理布局会更容易:

flowLayout.minimumLineSpacing = 0
flowLayout.minimumInteritemSpacing = 0

看起来集合视图可能正在尝试允许多个“间隙”,导致它认为只有一个单元格适合宽度。

然后,在 cellForItemAt 中设置 .hConstraint

cell.hConstraint.constant = floor(collectionView.frame.size.width / 2)

这将产生以下输出:

UICollectionView没有加载所有可见的单元格。

在我看来,这比原始的(10, 10)行/项目间距要好一些:

UICollectionView没有加载所有可见的单元格。

如果需要更多的“内边距”,你可以调整 Bordered View 的顶部/左侧/右侧/底部约束。

英文:

With this line:

flowLayout.estimatedItemSize = UICollectionViewFlowLayout.automaticSize

you are not giving the Flow Layout any hint as to the item size.

So, Flow Layout essentially says:

  • I need another "row" of cells
  • the cell may be as wide as the collection view
  • so, just ask for One cell

as you start to scroll, the currently visible cell has defined its width, so the Flow Layout asks for another cell.

You can either provide an actual estimated item size, or override viewDidAppear() and do it there:

override func viewDidAppear(_ animated: Bool) {
	super.viewDidAppear(animated)
	if let fl = collectionView.collectionViewLayout as? UICollectionViewFlowLayout {
		// let's use estimated width of 40% so we know we can fit 2 cells per row
		//	use a "reasonable" value for the height
		fl.estimatedItemSize = .init(width: collectionView.frame.width * 0.4, height: 280.0)
	}
}

Edit

As you state in your comment, this doesn't quite work.

Experimenting a little bit, and changing 0.4 to 0.2 (which seems silly, but...) appears to fix it.

Couple notes though:

From my experience, it is much easier to manage layout like this if we set:

flowLayout.minimumLineSpacing = 0
flowLayout.minimumInteritemSpacing = 0

It appears collection view might be trying to allow for multiple "gaps" - causing it to believe only one cell will fit the width.

Then, in cellForItemAt set your .hConstraint:

cell.hConstraint.constant = floor(collectionView.frame.size.width / 2)

That gives this output:

UICollectionView没有加载所有可见的单元格。

which is, IMHO, a little bit better visual than the original (10, 10) line/item spacing:

UICollectionView没有加载所有可见的单元格。

You can adjust the Bordered View top/leading/trailing/bottom constraints if you want a little more "padding".

huangapple
  • 本文由 发表于 2023年3月7日 04:06:45
  • 转载请务必保留本文链接:https://go.coder-hub.com/75655369.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定