Swift中的UIView子类:在解包时发现IBOutlet为零

时间:2016-01-09 23:16:57

标签: ios swift uiview subclass

我正在尝试通过继承UIView在Swift中创建自定义视图,并且我有一个名为 MyViewPanel.xib 的视图板,其类已分配给MyCustomView。实施如下:

import UIKit
@IBDesignable
class MyCustomView: UIView {
 @IBOutlet weak var title: UILabel!

 var question: Question {
     didSet {
        print("did set question, title is: \(question.title)")
     }
 }

 override init(frame: CGRect) {
        super.init(frame: frame)
    }


required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }

override func drawRect(rect: CGRect) {
        let height = rect.height
        let width = rect.width
        let color: UIColor = UIColor.whiteColor()

        let drect = CGRect(x: (width * 0.25), y: (height * 0.25), width: (width * 0.5),height: (height * 0.5))
        let bpath: UIBezierPath = UIBezierPath(rect: drect)
        color.set()
        bpath.stroke()
    }

override func awakeFromNib() {
        super.awakeFromNib()
        print("awake from nib!")
        self.title.text = "Test title" // error: found nil while unwrapping an Optional Value 
    }
}

在运行期间,我遇到以下错误:

fatal error: unexpectedly found nil while unwrapping an Optional value

由于awakeFromNib()UIView中的第一个生命周期事件,我不明白为什么在这种情况下title UILabel为零。

修改

要使用此自定义视图,我只需在故事板上绘制一个UIView矩形,并将其类别分配给MyCustomView。在故事板viewDidLoad()的{​​{1}}方法中,我在自定义视图中设置了问题:

ViewController

2 个答案:

答案 0 :(得分:2)

代码部分看起来不错,但这表明插件未在接口构建器中正确连接。在界面构建器的“出口”部分中,您可以看到标题出口已连接,并且未显示指示错误的感叹号。此外,代码中的IBOutlet行应在其旁边有一个填充圆圈,表示插座已正确连接,并且从接口构建器正确分配了类。

答案 1 :(得分:1)

我想出了如何在我写的UIView子类的便捷初始化器中为UILabel设置文本:

@IBOutlet weak var messageLabel: UILabel!

init?(frame: CGRect, message: String) {
    super.init(frame: frame)

    guard let view = NSBundle.mainBundle().loadNibNamed("MyViewSubclass", owner: self, options: nil).first as? MyViewSubclass else {
        return nil
    }

    // Without the following line, my view was always 600 x 600
    view.frame = frame

    self.addSubview(view)

    guard let messageLabel = view.messageLabel else {
        return
    }

    messageLabel.text = message
}