如何使用 Initializer 为 IBOutlet 赋值?

How do I assign an IBOutlet a value using an Initializer?

我觉得 应该 工作的事情有困难,我想知道关于 IBOutlets 的初始化值是否有一些我不理解的事情。

所以我创建了一个 class 具有三个 IBOutlets。然后我为这些出口变量创建了初始值设定项。当我创建 class 的新实例并向其传递硬编码值时,我在 return 中得到 nil

所以我已经 println()'ed 传入的 settingLabel 值以确保传入的参数确实带有一个值,它返回为 "hello"预期的。然后我尝试将值分配给 settingsLabel.text,但是当我调用 println(settingsLabel.text) 时返回 nil.

(线程 1: EXV_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0))

我的问题是:

我在这里遗漏了什么and/or如何使用初始化程序为 IBOutlet 赋值?

这是我对初始化程序的调用:

let cell = SettingCell(settingLabel: "hello", settingSwitch: true, timeSetting: 3)

这是我的SettingCell.swiftclass:

class SettingCell: UITableViewCell {

    @IBOutlet weak var settingsLabel: UILabel!
    @IBOutlet weak var settingsSwitch: UISwitch!
    @IBOutlet weak var timeSetting: UILabel!

    override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
    }

    init(settingLabel: String, settingSwitch: Bool, timeSetting: NSNumber) {

        println(settingLabel) // returns hello <--------------------

        super.init(style: .Default, reuseIdentifier: "SwitchSettingCell")
        settingsLabel.text = settingLabel
        self.settingsSwitch.on = settingSwitch
        self.timeSetting.text = timeSetting.description as String

        println(settingsLabel.text) // returns nil <--------------------

    }

    required init(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }


    var cellDelegate: SettingCellDelegate?


    @IBAction func handledSwitchChange(sender: UISwitch) {

        self.cellDelegate?.didChangeSwitchState(sender: self, isOn:settingsSwitch!.on)


    }

    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
    }

    override func setSelected(selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)

        // Configure the view for the selected state
    }

}

我的故事板:

IBOutlet 关键字只是告诉 Xcode 视图应该在故事板中可见的一种方式。您可以在故事板中连接这些出口,这样做会导致变量被实例化并添加为故事板中的子视图,而不是在代码中。

在您的代码中,您正在以编程方式创建您的单元格,而不是从情节提要中创建(实际上,如果您尝试从情节提要中创建它们,您的应用程序将会崩溃,因为您尚未实现 init(coder:))。因此,您的变量没有理由 "outlets" 并且从未被初始化。您必须自己初始化它们,将它们添加为子视图和设置约束,所有这些都在代码中。

在你的初始化程序中,你的代码是无效的,因为你的变量仍然是 nil。事实上,在您的编辑中,您删除了可选的链接 ?s,这将导致您的应用程序崩溃,因为变量是强制展开的,但是 nil。这与 println(settingsLabel.text) 崩溃的原因相同。


编辑:

好的,所以你的问题是你想从情节提要中初始化你的单元格,但你却通过调用自定义初始化程序以编程方式进行。在 tableView(_:cellForRowAtIndexPath:) 中,您通过从重用队列中取出一个单元格来获取您的单元格:

let cell = tableView.dequeueReusableCellWithIdentifier("SettingsCell", forIndexPath: indexPath) as! SettingCell

(假设您已经在故事板中为您的单元格原型提供了标识符 "SettingsCell")

每当从故事板创建视图时,都会使用视图的 init(coder:) 初始化程序,因此您必须在 SettingCell 子类中提供它的实现。一旦单元格出队,单元格的出口将被初始化并添加为单元格的子视图。

因此,在单元格出队后,您可以设置标签并切换:

cell.settingsLabel.text = //...
cell.settingsSwitch.on = //...
cell.timeSetting.text = //...