首页 > 解决方案 > CollectionView.cellForItem 返回零

问题描述

我在 Storyboard 中创建了一个 collectionView,然后将 Delegate 和 DataSource 方法放在管理该屏幕的 ViewController 的扩展中。

collectionView 使用 layoutDelegate 来显示 4 x 4 网格的图像。所有单元格都显示在网格中,因此不可见的单元格不是问题,它们都是 classimageCVC的子类UICollectionViewCell

这一切加载都没有问题,但我现在想在将控制权传递给用户之前操​​纵四个随机图像。请注意,collectionView 在结束时可能还没有完全加载,我在方法viewDidLoad中调用了选择要操作的图像的例程。功能如下:changeImages()viewDidLayoutSubviews

func changeImages() {
    collectionView.layoutIfNeeded()

    let maxChanges = 30
    var imageIndex = 0
    var imageChanges 0

    while imageChanges < maxChanges {
        imageIndex = Int.random(in: 0..<(collectionView.numberOfItems(inSection: 0)))
        if let cell = collectionView.cellForItem(as: IndexPath(row: imageIndex, section: 0)) as? imageCVC {
            changeCell(cell)
            imagesChanges += 1
        }
    }
}

编辑:纳入山姆的建议(下),但它仍然总是返回nil!)

不幸的是,虽然imageIndex设置正确(所以集合知道它有多少元素),cellForItem调用总是返回 nil。我在函数的开头强制布局,但没有效果。

请问有人可以让我知道我做错了什么吗?提前谢谢了。

标签: swiftuicollectionview

解决方案


经过进一步调查,似乎collectionView数据直到之后才被加载 - 这对viewDidLayoutSubviews我来说似乎有点矛盾,但是嘿,我相信有一个很好的理由...... - 所以我已经实施了我认为变通。

我已将调用changeImages()从 中取出,viewDidLayoutSubviews并将其放入 a 的完成段中DispatchQueue.main...,写在 中viewDidLoad,如下所示:

DispatchQueue.main.asyncAfter(deadline: .now() + 0.3, execute: {
    self.changeImages()
})

本质上,我给系统时间(0.3 秒)来完成子视图的完全加载,而不是在我知道视图已完全加载时将我的代码实际放置在周期的正确部分。一个解决方案,但我怀疑是一个不雅的解决方案。

如果有人知道我应该如何接近它,我会很感兴趣。谢谢。


推荐阅读