从xib加载自定义视图后,IBOutlet属性为零

时间:2015-02-07 16:47:05

标签: ios swift uiview nib

IBOutlets发生了一些奇怪的事情。 enter image description here

在代码中,我尝试访问此属性,但它们是nil。代码:

class CustomKeyboard: UIView {

    @IBOutlet var aButt: UIButton!
    @IBOutlet var oButt: UIButton!

    class func keyboard() -> UIView {
        let nib = UINib(nibName: "CustomKeyboard", bundle: nil)
        return nib.instantiateWithOwner(self, options: nil).first as UIView
    }

    override init() {
        super.init()
        commonInit()
    }

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

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

    // MARK: - Private
    private func commonInit() {
        println(aButt)
        // aButt is nil

        aButt = self.viewWithTag(1) as UIButton
        println(aButt)
        // aButt is not nil
    }
}

6 个答案:

答案 0 :(得分:45)

这是预期的,因为在调用初始化程序时没有分配IBOutlet。你不需要commonInit,只需要覆盖awakeFromNib,如下所示:

override func awakeFromNib() {
    super.awakeFromNib()

    print(aButt)
}

答案 1 :(得分:4)

假设您尝试了用于连接IBOutlet的标准故障排除步骤,请尝试以下操作:

显然,在某些运行时情况下,您需要禁用从笔尖唤醒。

  override func awakeAfter(using aDecoder: NSCoder) -> Any? {
      guard subviews.isEmpty else { return self }
      return Bundle.main.loadNibNamed("MainNavbar", owner: nil, options: nil)?.first
  }

答案 2 :(得分:2)

您的笔尖可能未连接。我的解决方案非常简单。在项目的某个地方(我创建了一个名为UIViewExtension.swift的类),使用这个方便的connectNibUI方法添加UIView的扩展。

extension UIView {
    func connectNibUI() {
        let nib = UINib(nibName: String(describing: type(of: self)), bundle: nil).instantiate(withOwner: self, options: nil)
        let nibView = nib.first as! UIView
        nibView.translatesAutoresizingMaskIntoConstraints = false

        self.addSubview(nibView)
        //I am using SnapKit cocoapod for this method, to update constraints.  You can use NSLayoutConstraints if you prefer.
        nibView.snp.makeConstraints { (make) -> Void in
            make.edges.equalTo(self)
        }
    }
}

现在你可以在任何视图上调用此方法,在init方法中,执行以下操作:

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

答案 3 :(得分:0)

你是如何从控制器发起你的观点的?像这样:

var view = CustomKeyboard.keyboard()
self.view.addSubview(view)

答案 4 :(得分:0)

基于@ScottyBlades,我创建了这个子类:

class UIViewXib: UIView {
    // I'm finding this necessary when I name a Xib-based UIView in IB. Otherwise, the IBOutlets are not loaded in awakeFromNib.
    override func awakeAfter(using aDecoder: NSCoder) -> Any? {
        guard subviews.isEmpty else { return self }
        return Bundle.main.loadNibNamed(typeName(self), owner: nil, options: nil)?.first
    }
}

func typeName(_ some: Any) -> String {
    return (some is Any.Type) ? "\(some)" : "\(type(of: some))"
}

答案 5 :(得分:0)

您可能没有提到xib的FileOwner。 在文件所有者中而不是在视图身份检查器中提及其类。