【问题标题】:Collection View isn't being displayed, cellForItemAtIndexPath is never called不显示集合视图,永远不会调用 cellForItemAtIndexPath
【发布时间】:2016-04-23 04:07:40
【问题描述】:

我有一个UITableView,其中包含UIStackView 的自定义单元格。作为准备新单元格的一部分,当表格视图通过其cellForRowAtIndexPath 方法添加新单元格时,它会实例化并添加任何需要添加到单元格堆栈中的集合视图(MultaCollectionView 类型)和任何UILabel视图(一个单元格可能包括各种集合视图)。理论上,堆栈视图包含一系列标签和集合视图。

虽然标签显示正确,但集合视图在运行时并未显示。我试图显示的集合视图是在 .xib Interface Builder 文档中定义的。

Collection View 的 numberOfSectionsInCollectionView 方法被调用,但 collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) 方法从未被调用。

为什么从未调用过collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) 方法?为什么集合视图不在 Stack View 中呈现?

import UIKit
private let reuseIdentifier = "Cell"

class MultaCollectionView: UICollectionView, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout, UICollectionViewDelegate {
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        self.delegate = self
        self.dataSource = self
    }
    class func instanceFromNib() -> UICollectionView {
        return UINib(nibName: "multas", bundle: nil).instantiateWithOwner(nil, options: nil)[0] as! UICollectionView
    }

    func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
        return 1
    }


    func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return 2
    }

    func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCellWithReuseIdentifier(reuseIdentifier, forIndexPath: indexPath)
        return cell
    }

}

TableView通过以下方法添加Cells:

func addSubviewsToCellStack(cell: ArticuloTableViewCell, texto: [[String: String]]) {\            
    if isLabel == true {
            let label = UILabel()
            label.text = "blah"
            subview = label
            cell.textoStack.addArrangedSubview(subview)
        } else {
            let colview = MultaCollectionView.instanceFromNib() 
            cell.textoStack.addArrangedSubview(colview)
        }                        
    }

}

【问题讨论】:

  • 可能是您没有正确设置单元格的项目大小。请设置 CollectionView 范围内每个单元格的项目大小,然后检查!
  • 尝试将集合视图的背景颜色设置为 UIColor.greenColor,这样您就可以验证它的大小不是零像素。
  • 愚蠢的建议:做self.collectionView.delegate = self而不是self.delegate。

标签: ios swift xcode7


【解决方案1】:

由于您收到了对 numberOfSectionsInCollectionView 的回调,这表明数据源已正确连接,但如果根据当前布局显示单元格不可见,则 collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) 将不会被调用,直到它是需要的。单元格可能不可见的原因可能是因为您的 collectionView 的 sectionInsets 设置得足够大,以至于第一个单元格将位于 collectionView 的可见区域之外。

另一个原因可能是 collectionView 的框架太小而无法显示任何单元格。 如果您的collectionview 的大小为{0,0},您应该会收到numberOfSectionsInCollectionView 的调用,但不会收到对cellForItemAtIndexPath 的调用,因为这些单元格将不可见。

也许尝试确保您的 collectionView 具有足够大的框架大小以显示您希望看到的单元格。您可能正确地看到了 UILabel,因为它们有一个隐含的 intrinsicContentSize,这确保它们在 stackView 中显示良好,而 CollectionView 很高兴拥有 0,0 的大小,因为它可以使用任何其他大小。尝试给 collectionView 明确的宽度和高度约束,看看是否有帮助。

【讨论】:

  • 谢谢达拉斯。你的答案有正确的想法。我没有按照您的建议添加约束,而是覆盖了 UIView intrinsicContentSize() 方法,并且我的单元格开始显示。我添加了一个答案,说明我做了什么。
  • 这听起来是个好方法,但要小心依赖具有抗压缩/拥抱优先级的内在内容大小。我认为它们将默认为 750。因此,如果另一个同级视图具有可以接管的更强优先级,您的集合视图大小仍然会受到影响。
【解决方案2】:

我的假设是,由于这发生在 UITableView 的单元格内,每当表格视图单元格被放回“重用池”时,集合视图的代表就会断开连接或禁用。这取决于为表格视图提供单元格的代码(我们在代码示例中没有看到)。

其他地方也可能有一些代码从集合视图中清除数据源。 (不太可能但值得检查)

【讨论】:

    【解决方案3】:

    通过在我的UICollectionView 子类中覆盖UIViewintrinsicContentSize() 方法解决了这个问题,如下所示(查看this question):

    override func intrinsicContentSize() -> CGSize {
        return self.collectionViewLayout.collectionViewContentSize()
    }
    

    顺便说一句,我还忘记为 Cell 重用标识符注册一个类。于是我修改了初始化器:

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        self.delegate = self
        self.dataSource = self
        self.registerClass(UICollectionViewCell.self, forCellWithReuseIdentifier: reuseIdentifier)
    }
    

    【讨论】:

      【解决方案4】:

      我终于让它工作了。从故事板视图控制器转换到非故事板集合视图控制器时,您必须在推送到控制器时执行此操作:

      func showChatLogController(user: User) {
          let chatLogController = ChatLogController(collectionViewLayout: UICollectionViewFlowLayout())
          chatLogController.user = user
          chatLogController.hidesBottomBarWhenPushed = true
          navigationController?.pushViewController(chatLogController, animated: true)
      
      }
      

      更具体地说,您必须使用collectionViewLayout:UICollectionViewFlowLayout

      【讨论】:

        猜你喜欢
        • 2019-11-16
        • 1970-01-01
        • 1970-01-01
        • 2021-04-15
        • 2014-11-01
        • 2016-07-22
        • 1970-01-01
        • 1970-01-01
        • 2020-11-18
        相关资源
        最近更新 更多