为啥在集合视图单元格中以编程方式创建的按钮需要是惰性变量?

Posted

技术标签:

【中文标题】为啥在集合视图单元格中以编程方式创建的按钮需要是惰性变量?【英文标题】:Why does a button created programmatically in a collection view cell need to be a lazy var?为什么在集合视图单元格中以编程方式创建的按钮需要是惰性变量? 【发布时间】:2018-09-11 02:15:24 【问题描述】:

如果我在 collectionView 单元格中以编程方式创建按钮,如果我想触发添加的目标,为什么我需要将按钮设为惰性 var 而不是常量?

例如,

class Cell: UICollectionViewCell 

    let xButton: UIButton = 
        let button = UIButton(type: .system)
        button.addTarget(self, action: #selector(handleX), for: .touchUpInside)
        return button
    ()

    @objc func handleX() 
        print("123")
    

    ...other boiler plate code

如果按钮被选中,则永远不会打印 123,但如果我将按钮设置为惰性变量:

class Cell: UICollectionViewCell 

    lazy var xButton: UIButton = 
        let button = UIButton(type: .system)
        button.addTarget(self, action: #selector(handleX), for: .touchUpInside)
        return button
    ()

    @objc func handleX() 
        print("123")
     

    ...other boiler plate code

123 被打印出来。

我了解惰性存储属性是在第一次使用之前不计算初始值的属性。我不清楚为什么它对 UIButton 很重要。

【问题讨论】:

您需要延迟创建按钮,以便您可以访问self,直到创建单元格后才可用。或者,您可以稍后分配目标/操作。 @vacawama 您应该发表您的评论作为答案。另一个回答的人没有像你那样回答“为什么”的问题。 @vacawama 如果您发表评论作为答案,我很乐意接受。这是一个很好、简单且易于理解的答案。谢谢! 【参考方案1】:

您需要将按钮创建为lazy,以便您可以访问self,直到创建单元格后才可用。所以,问题不在于按钮本身的创建,而是需要访问self 的目标/动作的设置。

或者,您可以稍后在将按钮添加到单元格的视图层次结构时分配目标/操作。

【讨论】:

【参考方案2】:

您不必延迟初始化变量,除非您需要实例本身,就像使用 addTarget() 一样。

【讨论】:

以上是关于为啥在集合视图单元格中以编程方式创建的按钮需要是惰性变量?的主要内容,如果未能解决你的问题,请参考以下文章

在 TableViewHeader 中以编程方式调用 IBAction

以编程方式创建形状视图并在集合视图单元格上使用

为啥两个表格视图单元格中的两个集合视图在 Swift 4 中不起作用?

将 xib 创建的单元格中的按钮连接到选项卡式视图应用程序中的视图

集合视图单元格中的动态按钮宽度

单元格子视图约束在 CellForRowAtIndex 中以编程方式更改