为啥在索引路径中的 UICollectionView 的 cellForItem 在一开始就被所有单元格调用

Posted

技术标签:

【中文标题】为啥在索引路径中的 UICollectionView 的 cellForItem 在一开始就被所有单元格调用【英文标题】:Why does UICollectionView's cellForItem at index path get called for ALL cells right at the start为什么在索引路径中的 UICollectionView 的 cellForItem 在一开始就被所有单元格调用 【发布时间】:2017-10-12 15:56:17 【问题描述】:

为什么 UICollectionView 的 cellForItem 在索引路径中,在显示之前被所有单元格调用。 collectionView 不应该只获取它需要的单元格......即将像 tableview 一样显示在屏幕上的单元格?

步骤

带有 ViewController 的故事板。 ViewController 有 CollectionView。 CollectionView 具有垂直流布局。

ViewController 拥有 collectionView 的 IBOutlet 并实现了 collectionView 的数据源和委托方法

在数据源和委托方法中,单元格(其大小使用自动布局)被传递到 collectionview .. 单元格以获取索引路径中的项目

在传递单元格之前放置一个打印语句,表明在集合视图显示在屏幕上之前请求所有单元格。

import UIKit

class ViewController: UIViewController 
    @IBOutlet weak var collectionView: UICollectionView!

    override func viewDidLoad() 
        super.viewDidLoad()

        var flowLayout=collectionView.collectionViewLayout as! UICollectionViewFlowLayout;
        flowLayout.estimatedItemSize = CGSize(width:20,height:30);
        self.collectionView.register(UINib(nibName:"ShortCell", bundle:nil), forCellWithReuseIdentifier: "ShortCell");
        self.collectionView.register(UINib(nibName:"LongCell", bundle:nil), forCellWithReuseIdentifier: "LongCell");
    


extension ViewController:UICollectionViewDelegate,UICollectionViewDataSource
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int 
        return 500;
    

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell 
        let row=indexPath.row;
        print("row:",indexPath.row);
        let rem = row % 2;
        if(rem==0)
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "ShortCell", for: indexPath);
            return cell;
        
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "LongCell", for: indexPath);
        return cell;
    

为什么collectionview需要在显示之前获取所有单元格?为什么它不像 tableview 那样只以零碎的方式请求单元格?这是个问题吗?

【问题讨论】:

嗯?我刚刚在一个新的测试视图控制器中运行了您的代码,并且只请求了可见和部分可见的单元格。 您的单元格是否使用自动布局来调整其大小? 我刚刚在外部 xib 文件中创建了基本单元格,并在没有编辑的情况下运行了您的代码。 【参考方案1】:

经过一番调查……

当使用flowLayout.estimatedItemSize 时,自动布局会通过布局来计算有多少单元格适合在估计的大小,忽略实际中的任何自动调整大小细胞。

因此,如果您将.estimatedItemSize 更改为实际的估计大小,您应该只根据需要获得(大约)对cellForItemAt 的调用次数。

请注意不要高估大小。如果你这样做,你要么最终得到一大堆

未定义 UICollectionViewFlowLayout 的行为,因为: item 的宽度必须小于 UICollectionView 的宽度减去 section insets 左右值,减去 content insets 左右值。

错误消息,或者你得到愚蠢(不准确)大小的滚动指示器。

【讨论】:

使我的估计大小接近单元格的实际大小,并且 uicollectionview 开始按预期工作,仅在需要时获取单元格!感谢您的提示:)

以上是关于为啥在索引路径中的 UICollectionView 的 cellForItem 在一开始就被所有单元格调用的主要内容,如果未能解决你的问题,请参考以下文章

404页面做好后,在iis设置404的url 为啥蜘蛛索引不存在的页面的时候返回的是200啊,我应该如何设置404

为啥 Stack 使用基于 1 的索引而不是 Java 中的 Array 中的基于 0 的索引?

如何在 Collection 视图中为每个单元格添加 edgeInsets -Swift

为啥查询不使用Oracle中的索引

为啥我在 postgresql 中的视图不使用索引?

为啥R中的回归会删除因子变量的索引1? [复制]