【问题标题】:Collection view cellForItemAt indexPath not getting called (Swift)集合视图 cellForItemAt indexPath 没有被调用(Swift)
【发布时间】:2017-02-25 08:40:29
【问题描述】:

我从故事板创建了一个集合视图控制器,并将其自定义类设置为ItemCollectionVC,其单元格的自定义类设置为ItemCell,并将其重用标识符设置为Cell

这是我的ItemCollectionVC 课程:

import UIKit

private let reuseIdentifier = "Cell"

class ItemCollectionVC: UICollectionViewController {

var dataSourceItems: [Items] = []
var counterBuildItems: [Items] {
    let weaponItemArray = WeaponItems.weaponItems as [Items]
    let defenseItemArray = DefenseItems.defenseItems as [Items]
    return weaponItemArray + defenseItemArray
}
var freeBuildItems = WeaponItems.weaponItems as [Items]
var captureKrakenItems: [Items] {
    let weaponItemArray = WeaponItems.weaponItems as [Items]
    let abilityItemArray = AbilityItems.abilityItems as [Items]
    return weaponItemArray + abilityItemArray
}

override func viewDidAppear(_ animated: Bool) {

    switch self.presentingViewController!.title! {
    case "CounterBuildVC":
        dataSourceItems = counterBuildItems
    case "FreeBuildVC":
        dataSourceItems = freeBuildItems
    case "CaptureKrakenVC":
        dataSourceItems = captureKrakenItems
    default:
        break
    }
}

override func numberOfSections(in collectionView: UICollectionView) -> Int {
    return 1
}

override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return dataSourceItems.count
}

override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath) as! ItemCell
    cell.cellImage.image = dataSourceItems[indexPath.row].image
    print(dataSourceItems.count)

    return cell
}
}

当集合视图控制器出现时,它是空的,什么可能导致问题?

【问题讨论】:

  • 您检查过数组的计数并重新加载您的集合视图吗?
  • 你在哪里调用集合视图实例上的reloadData()
  • @vadian 我没叫它,我必须叫它吗?
  • 我的错,你不必这样做,这是UICollectionViewController
  • @MandeepSingh 我查过了,没问题

标签: ios swift uicollectionview


【解决方案1】:

导致此问题的三件事之一,几乎每次我都遇到它,在 TableView 或CollectionView

1) 您的ViewController 不是您的UICollectionView 的数据源

2) numberOfRowsnumberOfSections 方法返回 0

3) 单元格的高度为 0,可能是由于约束问题,或者 heightForCell 方法未/未正确实现。

不可能说哪一个是您的问题,而且您总是可能遇到了一些奇怪的事情。在探索不太可能的选项之前,请确保这些都不是您的问题。

【讨论】:

  • 1.这是一个 UICollectionVC,而不是 UIViewController; 2、item和section都不为0; 3.我没有任何限制
  • A UICollectionViewController 是一个 UIViewController,而 CollectionView 有一个 UICollectionViewDataSource 作为它的数据源(不过,我很确定您使用 UICollectionVC 会将您的 VC 指定为数据源)。我之所以提到这些,是因为我之前遇到过很多次您遇到的确切问题,原因是简单的编码错误,而其中一个一直是原因。高度为 0 的单元格始终是最难调试的,因为它的价值。如果同时调用 numberOfSections 和 numberOfItems,这可能是您的问题。
  • 另外,更正(抱歉):可能是包含视图高度/大小的问题,而不是单元格大小。这里有几个相关的问题:stackoverflow.com/questions/34847069/…stackoverflow.com/questions/14668781/…
  • 我认为这可能与布局有关,Xcode 给了我一个错位的视图警告,我永远无法通过单击修复错位来修复它
  • 更新:这实际上是@Ahmad 的回答,感谢您指出问题
【解决方案2】:

如果你很确定collectionView 的dataSource 连接到viewController(默认情况下应该是),那么你应该reloadData(),因为collectionView 是从dataSourceItems 读取的。要理解这种情况,在cellForItemAt 中添加一个断点,在viewDidAppear 中添加另一个断点,然后检查哪个是第一个调用的?

override func viewDidAppear(_ animated: Bool) {

    switch self.presentingViewController!.title! {
    case "CounterBuildVC":
        dataSourceItems = counterBuildItems
    case "FreeBuildVC":
        dataSourceItems = freeBuildItems
    case "CaptureKrakenVC":
        dataSourceItems = captureKrakenItems
    default:
        break
    }

    collectionView.reloadData()
}

希望有所帮助。

【讨论】:

  • 在添加无意义的评论之前,正如我在答案中提到的,添加两个断点并检查会发生什么。加油:)
  • 但是viewDidAppear会先被调用,是不是意味着不重新加载数据应该有问题?
  • viewDidAppear 在 cellForItemAt 之前调用?!
  • @BrightFuture 这不应该发生 :) 确保我说的是 viewDidAppear,而不是 viewDidLoad。 cellForItemAt 应该在 viewDidAppear 之前运行(viewDidLoad 第一个方法应该被调用),所以 dataSourceItems 仍然是空的,即 numberOfItemsInSection 为 0;调用 viewDidAppear 后,dataSourceItems 应该包含数据……就是这样
  • 第一次调用numberOfItemsInSection为0,reloadData后为24
【解决方案3】:

如果您使用 故事板

,您很容易错过一些事情

1) 不要忘记单元格中的内容必须有连接的 Top、Bottom 约束和 内容视图必须有高度,这个单元格会知道为单元格设置高度。如果没有这些,单元格高度将为 0,并且函数 cellForItemAt 将永远不会被调用。

2)如果使用此功能,您可以使用单元格布局来设置单元格的动态单元格和高度:

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

【讨论】:

  • 有用的答案。谢谢埃格松。
【解决方案4】:

您必须在 viewWillAppear 中添加您的代码,然后它才能正常工作。 /*

override func viewDidAppear(_ animated: Bool) {

switch self.presentingViewController!.title! {
case "CounterBuildVC":
    dataSourceItems = counterBuildItems
case "FreeBuildVC":
    dataSourceItems = freeBuildItems
case "CaptureKrakenVC":
    dataSourceItems = captureKrakenItems
default:
    break
}

}

像这样:-

override func viewWillAppear(_ animated: Bool) {

     switch self.presentingViewController!.title! {
case "CounterBuildVC":
    dataSourceItems = counterBuildItems
case "FreeBuildVC":
    dataSourceItems = freeBuildItems
case "CaptureKrakenVC":
    dataSourceItems = captureKrakenItems
default:
    break
}
}

*/

【讨论】:

  • 当我们为 UICollectionViewController 创建类时,Xcode 会自动创建它。你可以创建一个类并检查它。
  • 实际上,教程中明确告诉我要删除它,而在我删除它之前它并没有效果
  • @BrightFuture,请更改集合视图和单元格的背景颜色。并查看您的集合视图和单元格是否已创建。我现在也面临同样的问题。
  • @MandeepSingh 有趣的方法。集合视图已创建,但单元格可能未创建,因为我看不到它。
  • 我认为@dylanthelion 有道理,我猜我遇到了一些布局问题,因为 Xcode 给了我一个错位的视图警告,我永远无法通过单击修复错位来修复它
【解决方案5】:

在我的情况下,集合视图 contentInset 存在问题,请尝试在您的集合视图子类中添加以下代码。


override func layoutSubviews() {
    super.layoutSubviews()
    self.contentInset = UIEdgeInsetsMake(0, 0, 0, 0)
}

override func reloadData() {
    DispatchQueue.main.async {
        super.reloadData()
    }
}

【讨论】:

    【解决方案6】:

    检查您是否在集合视图的 numberOfItemsInSection 方法中获得了正确数量的部分。

    如果要向集合视图添加流布局,请移除流布局,并检查集合视图单元格现在是否显示。

    如果他们这样做,只需调整您的集合视图流布局代码,它应该看起来像这样

    let _flowLayout = UICollectionViewFlowLayout()
    _flowLayout.sectionInset = UIEdgeInsets(top:0, left: 0, bottom: 0, right: 0)
    _flowLayout.scrollDirection = .vertical
    yourCollectionView.collectionViewLayout = _flowLayout
    

    您可以设置插图以适合您的使用。

    【讨论】:

      【解决方案7】:

      我通过正确初始化 UICollectionView 解决了我的问题,如下所示:

      fileprivate let collectionView = UICollectionView(frame: CGRect.zero, collectionViewLayout: UICollectionViewFlowLayout.init()) 
      

      【讨论】:

        猜你喜欢
        • 2018-01-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多