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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/28384721/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 04:43:43  来源:igfitidea点击:

IBOutlet properties nil after custom view loaded from xib

iosswiftuiviewnib

提问by Gralex

Something strange going on with IBOutlets. enter image description here

IBOutlets 发生了一些奇怪的事情。 在此处输入图片说明

In code I've try to access to this properties, but they are nil. Code:

在代码中,我尝试访问此属性,但它们是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
    }
}

回答by fz.

That's expected, because the IBOutlet(s) are not assigned by the time the initializer is called. You don't need the commonInit, just an override of awakeFromNib as follows:

这是意料之中的,因为在调用初始化程序时尚未分配 IBOutlet。您不需要 commonInit,只需重写awakeFromNib,如下所示:

override func awakeFromNib() {
    super.awakeFromNib()

    print(aButt)
}

回答by ScottyBlades

Assuming you tried the standard troubleshooting steps for connecting IBOutlets, try this:

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

Apparently, you need to disable awake from nib in certain runtime cases.

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

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

回答by Josh O'Connor

Your nib may not be connected. My solution is quite simple. Somewhere in your project (I create a class called UIViewExtension.swift), add an extension of UIView with this handy connectNibUI method.

您的笔尖可能未连接。我的解决方案很简单。在您的项目中的某个地方(我创建了一个名为 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)
        }
    }
}

Now you can call this method on any view, in your init method, do this:

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

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

回答by Chris Prince

Building on @ScottyBlades, I made this subclass:

基于@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))"
}

回答by szpetip

And how did you initiate your view from the controlller? Like this:

你是如何从控制器启动你的视图的?像这样:

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