【问题标题】:cellForItemAtIndexPath not called but numberOfItemsInSection does未调用 cellForItemAtIndexPath 但 numberOfItemsInSection 调用
【发布时间】:2015-08-28 13:46:27
【问题描述】:

这可能是重复的帖子,但我没有找到解决方案。

我将我的UICollectionView 设置为:

UINib *nib = [UINib nibWithNibName:@"CollectionViewCell"
                           bundle:[NSBundle mainBundle]];
[_collectionView registerNib: nib forCellWithReuseIdentifier:@"bCell"];

(我尝试设置委托,没有委托等)。

然后,只有

- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section 被调用,而

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath 没有。

我检查了返回的 numberOfItemsInSection,它始终 > 0(正好是 17)。

我已经确认要致电[_collectionView reloadData];,但也没有任何反应。

我尝试了不同的方法,但无法成功。

此外,我的UICollectionView 应该在这里,但不是:

有人知道吗? 谢谢。

【问题讨论】:

  • 你添加了“numberofsectionsincollectionview”方法吗?请输入委托和数据源方法,我们可以为您提供更多帮助。
  • collectionView:cellForItemAtIndexPath: 只有在项目存在(即 indexPath 的项目)并且可见时才会被调用。例如,细胞的大小是多少?您是否在它们之间放置了一些“空格”等。您是否在主线程中调用reloadData

标签: ios objective-c uicollectionview


【解决方案1】:

1.当您在 numberOfItemsInSection 方法上返回超过 0 个项目时,将调用 cellForItemAtIndexPath。

2。检查您的 UICollectionViewFlowLayout 是正确的还是您自己的。 UICollectionViewLayout 是抽象类,不能直接使用

3.检查集合视图单元格和集合视图的大小。

4.尝试在代码中设置您的 collectionview 大小。 [yourCollectionViewFlowLayout setItemSize:CGSizeMake(200, 200)];

5.如果其中任何一个不起作用,则终止 XCode 并重新启动。有时它会解决问题。

苹果说

UICollectionViewLayout 类是一个抽象基类,您可以将其子类化并用于生成集合视图的布局信息。布局对象的工作是确定单元格、补充视图和装饰视图在集合视图边界内的位置,并在被询问时将该信息报告给集合视图。集合视图然后将提供的布局信息应用到相应的视图,以便它们可以呈现在屏幕上。

您必须继承 UICollectionViewLayout 才能使用它。不过,在考虑子类化之前,您应该查看 UICollectionViewFlowLayout 类,看看它是否可以适应您的布局需求。

【讨论】:

  • 我没有很好地解释它,但这与数字有关:**我检查了我返回的计数,它总是 > 0(它正好是 17)。 **
  • collectionViewContentSize 不能是.zero,否则cellForItemAt 将不会被调用。
【解决方案2】:

好的,我认为这对未来的问题很有用......

这是因为 StoryBoard 的限制。我真的不明白为什么会发生这种情况,因为我刚刚固定了一个水平空间。我删除了水平空间作为该视图的约束,一切正常。

好吧,让我们生活下去吧。

【讨论】:

  • 我缺少高度限制。感谢您的提示。肯定为我节省了一些时间。 :)
  • 寻找collectionView的具体约束。就我而言,最重要的约束是尝试使用已删除的元素设置距离..
  • 奇怪的是,这仍然有效。 :) 我真的很想弄清楚问题出在哪里,然后在我看到这个之后,就创建了一个高度限制并开始工作。
  • 非常感谢!我认为苹果有这个问题有点愚蠢。也许我不想要约束!
  • 经过几天的调试,这就是问题所在!谢谢拉斐尔!
【解决方案3】:

帮助我的是设置正确的itemSize。由于高度错误,我的cellForItemAtIndexPath 没有被调用。

所以我将大小设置为:

[self.myCollectionViewFlowLayout setItemSize:CGSizeMake(170, 300)];

【讨论】:

    【解决方案4】:

    对我来说,问题是我正在以编程方式创建我的收藏视图,但我已将其指定为 CGRectZero 作为其框架。我在viewDidLoad 之后使用自动布局进行布局。如果我在加载视图控制器时布置集合视图,它最终会正确调用cellForItemAtIndexPath:

    【讨论】:

      【解决方案5】:

      我也面临同样的问题,最后知道我为 collectionViewLayout 传递了错误的类对象,我在为 UICollectionView 创建对象时更改为 UICollectionViewFlowLayout 而不是 UICollectionViewLayout在它凝视的下方调用所有委托方法。

       collectionView = UICollectionView(frame: CGRectMake(5, 0, 400, 40) , collectionViewLayout: UICollectionViewFlowLayout())
      

      【讨论】:

      • 我只花了大约 2 个小时——终于——找到了这个错误,我希望我能在之前看到这个答案!
      • 哇,我希望我以前也读过这个。谢谢你。仅供任何可能以编程方式创建UICollectionView 的人参考
      • 谢谢!搜索了两个小时,找到了这个!
      【解决方案6】:

      我也遇到了这个问题。我检查了所有可能的问题,一切看起来都很好。然后我尝试更改重新加载方法。

      [self.colView reloadData] -> [self.collectionView reloadSections:[NSIndexSet indexSetWithIndex:x]];

      然后一切正常。但是我仍然不明白如何。

      【讨论】:

      • 真是个错误! >:(谢谢你的解决方案。
      • 这是什么原因?只有这对我也有用。
      • @frank x 听到了什么?
      • @Muju 您要重新加载的部分。
      【解决方案7】:

      将此添加到 viewDidLoad:

      self.automaticallyAdjustsScrollViewInsets = NO;
      

      【讨论】:

      • 最佳答案,浪费了我一天。
      • 而iOS13修复了这个bug。
      【解决方案8】:

      我刚刚发现只要至少一个单元格的高度为零,就不会调用任何 cellForItemAtIndexPath(在 iOS 10 中)。

      免责声明:抱歉,如果这应该是评论 - 声誉不够。

      【讨论】:

      • 如果同一部分有正数numberOfItemsInSectionsizeForItemAtIndexPath 似乎无法返回零
      【解决方案9】:

      我在带有“标准”约束(底部、顶部、前导、尾随固定到内部视图)的情节提要上的集合视图出口遇到了同样的问题。

      我是这样解决的:

      let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout()
      layout.itemSize = self.collectionView.frame.size
      

      【讨论】:

        【解决方案10】:

        对我来说,我的 collectionView 的容器没有 translatesAutoresizingMaskIntoConstraints = false

        【讨论】:

          【解决方案11】:

          我也遇到过类似的问题。问题在于部分中的 numberOfItems。 如果您的节数或节中的行数低于零,则可能不会调用您的 cellForRowAtIndexPath。

          【讨论】:

            【解决方案12】:

            对我来说,cellForItemAtIndexPath 在我将 collectionView 的约束设置为 0 并再次将其设置为实际大小后第一次没有调用。

             @IBOutlet weak var collectionVwHeightContraint: NSLayoutConstraint!
             if attachments.count > 0 {
            
                 collectionVwHeightContraint.constant = 100
             }else {
            
                 collectionVwHeightContraint.constant = 0
             }
             // collectionVwHeightContraint is my collectionView height Contraint outlet
            

            我通过调用解决了这个问题:

            self.view.layoutIfNeeded()
            

            希望对某人有所帮助:)

            【讨论】:

              【解决方案13】:

              就我而言,我搞砸了我的自定义单元格标签约束。再次验证您的约束。

              【讨论】:

                【解决方案14】:

                reza_khalafi 答案对我有用,我使用的是 Xcode 11 和 swift 4.2。 swift 4.2 版本的 reza 的答案。

                在 viewDidLoad 上添加这个

                self.automaticallyAdjustsScrollViewInsets = false
                

                【讨论】:

                  【解决方案15】:

                  可能会帮助其他人,可能是两件事:

                  1. 单元格高度计算不正确,需要检查单元格的约束条件。

                  为了解决这个问题,我实现了 UICollectionViewLayout 的方法: 扩展 TableViewCellActionItemPageControl: UICollectionViewDelegateFlowLayout {

                  func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
                      return CGSize(width: 414, height: 213) 
                  }
                  
                  1. 其他可能性是:返回的集合视图单元格的大小大于集合视图本身。确保你的单元格的高度小于你的集体的高度。

                  【讨论】:

                    【解决方案16】:

                    在我的例子中,collectionViewCell 的高度大于 CollectionView 的高度。

                    【讨论】:

                      【解决方案17】:

                      就我而言,它可以交替工作。 然后我在主线程上运行 reloadData() 并修复了问题。 但后来在某些更改之后再次出现相同的问题。最后,我把它变成了下面这样。现在没有问题,我觉得 self.view.layoutIfNeeded() 起着关键作用

                      DispatchQueue.main.async {
                                      self.view.layoutIfNeeded()
                                      self.collectionView.reloadData()
                                  }
                      

                      【讨论】:

                        【解决方案18】:

                        完成@frank 回答:(快速回答)

                        extension UICollectionView {
                           func reloadFirstSection() {
                                let indexPath = IndexPath(item: 0, section: 0)
                                reloadSections(IndexSet(integer: indexPath.section) )
                            }
                        }
                        

                        然后代替collectionView.reloadData()调用collectionView.reloadFirstSection()

                        【讨论】:

                          猜你喜欢
                          • 1970-01-01
                          • 1970-01-01
                          • 1970-01-01
                          • 1970-01-01
                          • 2017-11-13
                          • 2014-08-17
                          • 1970-01-01
                          • 1970-01-01
                          • 2021-07-04
                          相关资源
                          最近更新 更多