collectionView cellForItemAt 没有被调用

Posted

技术标签:

【中文标题】collectionView cellForItemAt 没有被调用【英文标题】:collectionView cellForItemAt not being called 【发布时间】:2018-07-12 05:38:15 【问题描述】:

我有一个UITableView,其中每个原型单元格中都有一个UICollectionView。这个集合视图应该是一个图像网格。我对 Swift 很陌生,已经搜索了几个小时(并且阅读了大量 *** 文章),但似乎无法找到这个问题的正确答案。

collectionView cellForItemAt 怎么没有被调用?

我看到我的 collectionView numberOfItemsInSection 方法和 collectionView sizeForItemAt 方法被调用。我确保将我的TableViewCell 指定为collectionView 的委托和数据源。我在带有插座的 Interface Builder 中都这样做了,在我的自定义 TableViewCell 的 awakeFromNib 方法中再次使用

cardImagesCollection.delegate = self
cardImagesCollection.dataSource = self

无论我做什么,我似乎都无法得到这个称呼。我确保我设置了良好的约束,因为这让我在 tableViewCells 上烧了一次。

为了我的一生,我无法让它加载 collectionView。

任何帮助将不胜感激。

具体来说,我使用的是 Xcode 9.4.1 和 Swift 4.1。

谢谢

编辑 - 添加示例代码

HomeViewController: UIViewController

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
    let cell = tableView.dequeueReusableCell(withIdentifier: "LatestCardCell", for: indexPath) as! LatestCardsTableViewCell

    cell.backgroundColor = UIColor.clear
    cell.card = cards[indexPath.row]
    return cell

LatestCardsTableViewCell: UITableViewCell

@IBOutlet weak var cardImagesCollection: UICollectionView!

var card: Card! 
    didSet 
        titleLabel.attributedText = FontUtil.attributedCardTitleText(string: card.title)
        descriptionLabel.attributedText = FontUtil.attributedCardDescriptionText(string: card.description)
    


func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int 
    print("count")
    return card.imageUrls.count


func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell 
    print("here")
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "LatestCardsImage", for: indexPath as IndexPath) as! LatestCardImageCell

    //let url = card.imageUrls[indexPath.row]
    //cell.imageView.image = UIImage(named: "test")

    cell.backgroundColor = UIColor.blue
    return cell


func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize 
    return CGSize(width: 150, height: 150)

LatestCardImageCell: UICollectionViewCell

@IBOutlet weak var imageView: UIImageView!

编辑 2:我尝试过的建议摘要

人们建议在我构建 CollectionView 的 cellForRowAt 调用中为 CollectionView 设置数据源和委托:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
    let cell = tableView.dequeueReusableCell(withIdentifier: "LatestCardCell", for: indexPath) as! LatestCardsTableViewCell

    cell.cardImagesCollection.delegate = cell
    cell.cardImagesCollection.dataSource = cell
    cell.backgroundColor = UIColor.clear
    cell.card = cards[indexPath.row]
    return cell

这并没有改变任何东西。他们还建议在设置 cell.card 后立即在该 cellForRowAt 调用中添加以下内容:

cell.cardImagesCollection.reloadData()

这也没有改变任何东西。

我已经在 TableViewCell 的自定义类中设置了断点和日志记录,我可以看到 numberOfItemsInSection 每个 TableViewCell 调用一次,它返回正确的数字(这个数字因 TableViewCell 而异)。然后我还看到sizeForItemAt 被调用的确切次数是numberOfItemsInSection 返回的次数。但是,我没有看到 cellForItemAt 方法被调用过。

这是日志记录:

numberOfItemsInSection: 6
sizeForItemAt: Section 0 Row 0
sizeForItemAt: Section 0 Row 1
sizeForItemAt: Section 0 Row 2
sizeForItemAt: Section 0 Row 3
sizeForItemAt: Section 0 Row 4
sizeForItemAt: Section 0 Row 5
numberOfItemsInSection: 2
sizeForItemAt: Section 0 Row 0
sizeForItemAt: Section 0 Row 1
numberOfItemsInSection: 4
sizeForItemAt: Section 0 Row 0
sizeForItemAt: Section 0 Row 1
sizeForItemAt: Section 0 Row 2
sizeForItemAt: Section 0 Row 3

有些人建议确保通过使用自动完成而不是复制和粘贴来定义cellForItemAt,我一开始就是这样做的。我还使用以下协议 UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout 设置了我的自定义 TableViewCell,它不会抱怨缺少 cellForItemAt 方法。我目前在 InterfaceBuilder 中设置了委托和数据源,这就是我所看到的方法调用的原因。

我尝试在多个位置调用 collectionView 上的reloadData()(第二次我在cellForRowAtdidSet 调用中设置了cell.card,甚至在自定义 TableViewCell 中设置了awakeFromNib 方法. 没有任何效果。

TableCell 的其他方面呈现,但不是这个图像集合。我在 InterfaceBuilder 中硬编码了 CollectionView 单元格的大小,甚至覆盖了 sizeForItemAt 以始终​​返回 CGSize(width: 150, height: 150),只是为了确保问题不在于单元格太小而无法看到。 tableView 单元格使用latestCardsTableView.rowHeight = UITableViewAutomaticDimension 设置为自动高度,我在标签中添加了长文本,以确保它们的大小随着文本自动增长。

还有人有其他想法吗?有没有我可以从 InterfaceBuilder 截屏的东西,或者我可以编写一些 Swift 代码来强制执行一些 AutoLayout 的东西?我对任何事情都持开放态度。

编辑 3:一线希望

我发现如果我给我的 UITableViewCell 一个显式的大高度,UICollectionView 会显示并调用cellForItemAt。那么,鉴于我在 TableView 上设置了 rowHeight = UITableViewAutomaticDimension,我该如何设置约束,以便 UICollectionView 强制 UITableViewCell 更大?

【问题讨论】:

可以查看你的示例代码吗? 没有看到任何代码我们如何理解您的问题,有很多方法可以解决此类问题,您可以显示您的代码 复制粘贴可能是功能不对,自己写试试,用自动补全 您的代码可以更好地理解您的问题。 确保 UITableViewCell 的高度不为零(表示 UICollectionView 已显示)。 【参考方案1】:

也许您可以执行以下操作, 在您的 LatestCardsTableViewCell 类中编写一个方法,

func configureCell() 
      cardImagesCollection.reloadData()

并在 HomeViewController 的 cellForRowAtIndexPath 中调用此方法,如下所示,

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
let cell = tableView.dequeueReusableCell(withIdentifier: "LatestCardCell", for: indexPath) as! LatestCardsTableViewCell

cell.backgroundColor = UIColor.clear
cell.card = cards[indexPath.row]
cell. configureCell()
return cell

【讨论】:

我确实尝试过,但它也不起作用。实际上,我什至尝试将 cardImagesCollection.reloadData() 放在我的 didSet 中作为卡片,因为这是 CollectionView 提供的图像。 您是否检查过在 cellForRowAtIndexPath 中添加断点?您确定该方法没有被调用吗? 是的。我还在该方法中添加了一个打印语句,但在我的控制台中什么也看不到。我将打印语句放入并且 numberOfItemsInSection 和 sizeForItemAt 被调用了正确的次数,但是 cellForItemAt 不打印任何内容并且不显示并且没有命中断点,所以我非常有信心它没有被调用。 您可以尝试删除collectionView的所有约束,然后通过选择“添加缺少的约束”来修复约束警告吗? 我认为您可以做的是,为您的集合视图高度设置一个 IBOutlet,@IBOutlet var height: NSLayoutConstraint 根据单元格的数量计算您的集合视图的高度,并将计算出的高度分配给上述出口。一旦你做得正确。 tableView 应该按照您的设置自动调整它的单元格高度,rowHeight = UITableViewAutomaticDimension

以上是关于collectionView cellForItemAt 没有被调用的主要内容,如果未能解决你的问题,请参考以下文章

在 UIcollectionview 中使多个单元格出列的方法

Swift-从另一个ViewController插入TableView中的项目

我显示了单元格,但是当我按下按钮时,我希望图像显示在集合视图单元格中

CollectionView 中的 CollectionView:使用 didSelectItemAt 执行Segue

为啥 CollectionView 单元格内部其他 collectionView 的大小错误?

CollectionView 单元格出现在 collectionView 之外。