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

时间:2016-11-24 05:12:11

标签: ios uiview swift3 xib nib

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

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

除了:作为第二个问题,我注意到我在xib文件中创建的GCDateView视图无法直接分配为主视图(例如,在init结束时我可以不要说self = gcDateViewView)。也许我需要一个单独的问题。

从父控制器/视图中:

let dv = GCDateView()

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

}

1 个答案:

答案 0 :(得分:5)

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

方法awakeFromNib确保所有IBOutlet个实例都已初始化:

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

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

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

用法:

let dateView = GCDateView.loadFromXIB()