我有一个包含多个单元格的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并且不添加视图。知道为什么会这样,怎么做?
答案 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