为什么在从XIB以编程方式创建UIView后,我的UILabel为零?(附代码)

Gre*_*reg 2 xib uiview nib ios swift3

问题:为什么UILabel在从XIB以编程方式创建UIView后,在init(代码附加)中没有?(参考下面的代码)这就是该行label1.text = "TBC - It was updated"引发错误

背景:我想以编程方式创建多个自定义视图,在这种情况下是多个GCDateView.我想使用一个XIB文件来布局自定义视图与关联类,以编程方式完成自定义,因此我在这里有一个GCDateView.swift和一个GCDateView.xib文件.

除了:作为第2搁置的问题,我注意到我从厦门国际银行文件GCDateView内创建视图不能直接分配是主视图(例如,在初始化结束时,我不能说self = gcDateViewView).也许我需要一个单独的问题.

从父控制器/视图中:

let dv = GCDateView()
Run Code Online (Sandbox Code Playgroud)

GCDateView:

import UIKit

class GCDateView : UIView {

    @IBOutlet weak var label1: UILabel!

    func commonInit() {
        // Programmtically use XIB file
        if self.subviews.count == 0 {
            let bundle = Bundle(for: type(of: self))
            let nib = UINib(nibName: "GCDateView", bundle: bundle)
            let gcDateViewView : UIView = nib.instantiate(withOwner: self, options: nil)[0] as! UIView
            gcDateViewView.frame = self.bounds
            gcDateViewView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
            addSubview(gcDateViewView)
        }
        **label1.text = "TBC - It was updated"  // ** ERROR: label1 was Nil ****
    }

    override init(frame: CGRect) {
        NSLog("GCDateView: Init frame")
        super.init(frame: frame)
        commonInit()
    }

    required init?(coder aDecoder: NSCoder) {
        NSLog("GCDateView: Init decoder")
        super.init(coder: aDecoder)
        commonInit()
    }

}
Run Code Online (Sandbox Code Playgroud)

Vla*_*pko 5

IBOutlet实例未初始化init?(coder aDecoder: NSCoder).
该过程在单独的步骤中完成.

有一种方法awakeFromNib可以保证所有IBOutlet实例都被初始化:

override func awakeFromNib() {
    super.awakeFromNib()
    label1.text = "TBC - It was updated" // Won't crash.
}
Run Code Online (Sandbox Code Playgroud)

要解决你的第二个问题(即避免添加另一个自我类型的实例作为自我子视图)我建议创建类方法,GCDateView通过从xib加载它来创建新实例.
这是更新的代码:

import UIKit

class GCDateView : UIView {

    @IBOutlet weak var label1: UILabel!

    class func loadFromXIB() -> GCDateView {
        let bundle = Bundle(for: type(of: self))
        let nib = UINib(nibName: "GCDateView", bundle: bundle)
        let gcDateView = nib.instantiate(withOwner: self, options: nil)[0] as! GCDateView
        gcDateView.frame = self.bounds
        gcDateView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        gcDateView.label1.text = "TBC - It was updated"

        return gcDateView
    }
}
Run Code Online (Sandbox Code Playgroud)

用法:

let dateView = GCDateView.loadFromXIB()
Run Code Online (Sandbox Code Playgroud)