Skip to main content
 首页 » 编程设计

swift之如何使用 Initializer 为 IBOutlet 赋值

2024年01月01日51tuyile006

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

所以我创建了一个包含三个 IBOutlet 的类。然后我为这些导出变量创建了初始值设定项。当我创建该类的一个新实例并向其传递硬编码值时,我得到 nil 作为返回。

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

(线程 1:EXV_BAD_INSTRUCTION(代码=EXC_I386_INVOP,子代码=0x0))

我的问题是:

我在这里遗漏了什么和/或如何使用初始值设定项为 IBOutlet 赋值?

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

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

这是我的SettingCell.swift类:

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 
    } 
 
} 

我的 Storyboard:

请您参考如下方法:

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

在您的代码中,您正在以编程方式创建您的单元格,而不是从 Storyboard 中创建(事实上,如果您尝试从 Storyboard 中创建它们,您的应用程序将会崩溃,因为您还没有实现 init(coder:)).因此,您的变量没有理由成为“导出”并且从未被初始化。您必须自己初始化它们,将它们添加为 subview 和设置约束,所有这些都在代码中。

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


编辑:

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

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

(假设您已在 Storyboard 中为您的单元格原型(prototype)提供标识符“SettingsCell”)

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

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

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