如何访问自定义CollectionView单元格的初始值设定项?

时间:2018-06-15 00:18:07

标签: ios swift uicollectionview uistackview

我有一个包含多个单元格的collectionView。每个单元都属于这一类:

class OuterCollectionViewCell: UICollectionViewCell {

    @IBOutlet weak var stackView: UIStackView!

    override init(frame: CGRect) {
        super.init(frame: frame)
        print("initting")
        for i in 1...30 {
            let view = UIView()
            view.backgroundColor = UIColor.red
            view.tag = i

            self.stackView.addSubview(view)
        }
    }
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }

}

我正在创建每个单元格,我希望将其称为初始化程序,如下所示:

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "outerCell", for: indexPath) as! OuterCollectionViewCell
    cell.backgroundColor = UIColor.gray
    return cell
}

我的目的是在此水平stackView中添加30个子视图,以便显示30个条纹。我想在init中以编程方式添加这些子视图,以避免在故事板中手动执行。但是现在不调用init并且不添加视图。知道为什么会这样,怎么做?

2 个答案:

答案 0 :(得分:1)

  

我希望将其初始化程序称为

你可以希望,但是,正如你正确地发现的那样,你注定要失望。通过调用dequeue生成的单元格永远不会调用init(frame:)

一个明显的解决方案是在cellForItemAt中添加30个子视图。如果这样做,您还需要包含一个测试,以确保下次重复使用单元格时不再添加 。换句话说,只有在它们不存在的情况下才添加它们。

更简单:既然您已经实现了init(coder:),为什么不将您的30-subviews代码移动到那个?这是一个初始化程序,当通过出列创建一个单元格时被调用,并且当一个单元格被重用时,将不会被调用(显然)。

但请注意,您正在做的事情还有其他问题。正如您的代码所代表的那样,您的视图没有大小,并且很难清楚堆栈视图将如何构建。此外,仅仅说addSubview不会导致堆栈视图对您的视图执行任何操作。所以基本上即使你的代码运行,我希望你实际上看不到任何东西。但是,让我们一次跨过一座桥。

答案 1 :(得分:0)

这里的另一个潜在问题是,如果要将自定义方法变量添加到初始化程序中。对于样式等...

我最终将所有布局代码提取到自己的方法中,该方法在dequeueReusableCell之后被调用。

let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as! Cell
cell.ifNeeded(layout: .someStyle)

然后有一个自定义变量,您可以跟踪初始化。

var layout:Layout?

如果已经布置好,然后退出。

func ifNeeded(layout:Layout) {
    //exit if already laid out
    guard self.layout == nil else { return }
    self.layout = layout