为什么 UICollectionView cellForItemat indexpath 会在一开始就为所有单元格调用

Why does UICollectionView's cellForItem at index path get called for ALL cells right at the start

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

步骤

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

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 那样只以零碎的方式请求单元格?这是个问题吗?

经过一番调查...

当使用 flowLayout.estimatedItemSize 时,自动布局会进行布局传递以计算有多少单元格将适合估计大小, 忽略实际单元格内的任何自动调整大小。

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

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

The behavior of the UICollectionViewFlowLayout is not defined because: the item width must be less than the width of the UICollectionView minus the section insets left and right values, minus the content insets left and right values.

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