Propriétés de l'IBOutlet nul après une vue personnalisée chargée à partir de xib

<!-Il se passe quelque chose d'étrange avec les IBOutlets. enter image description here

Dans le code, j'ai essayer d'accès à ces propriétés, mais ils sont nil. Code:

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
    }
}
20
demandé sur Sk0prion 2015-02-07 19:47:05

4 réponses

c'est normal, parce que les IBOutlet(s) ne sont pas assignés au moment où l'initialiseur est appelé. Vous n'avez pas besoin de la commonInit, juste un remplacement de awakeFromNib comme suit:

override func awakeFromNib() {
    super.awakeFromNib()

    print(aButt)
}
37
répondu fz. 2017-03-30 20:50:54

votre nib peut ne pas être connecté. Ma solution est très simple. Quelque part dans votre projet (je crée une classe appelée UIViewExtension.swift), ajoutez une extension D'UIView avec cette méthode pratique de connectNibUI.

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

Maintenant vous pouvez appeler cette méthode sur n'importe quelle vue, dans votre méthode init, faites ceci:

override init(frame: CGRect) {
    super.init(frame: frame)
    connectNibUI()
}
1
répondu Josh O'Connor 2016-11-30 23:23:37

et comment avez-vous initié votre vue depuis le contrôleur? Comme ceci:

var view = CustomKeyboard.keyboard()
self.view.addSubview(view)
0
répondu szpetip 2015-02-07 17:20:12

en supposant que vous avez essayé les étapes de dépannage standard pour connecter des IBOutlets, essayez ceci:

apparemment, vous devez désactiver awake from nib dans certains cas d'exécution.

  override func awakeAfter(using aDecoder: NSCoder) -> Any? {
      guard subviews.isEmpty else { return self }
      return Bundle.main.loadNibNamed("MainNavbar", owner: nil, options: nil)?.first
  }
0
répondu ScottyBlades 2018-09-20 04:07:20