web-dev-qa-db-fra.com

Propriétés IBOutlet nil après l'affichage personnalisé chargé depuis xib

Quelque chose d'étrange se passe avec IBOutlets .enter image description here

Dans le code, j'ai essayé d'accéder à ces propriétés, mais elles 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
    }
}
21
Gralex

Cela est prévu, car le ou les IBOutlet ne sont pas affectés au moment de l'appel de l'initialiseur. Vous n'avez pas besoin de commonInit, mais simplement d'un remplacement de awakeFromNib comme suit:

override func awakeFromNib() {
    super.awakeFromNib()

    print(aButt)
}
39
fz.

Votre nib ne peut pas être connecté. Ma solution est assez simple. Quelque part dans votre projet (je crée une classe appelée UIViewExtension.Swift), ajoutez une extension de UIView avec cette méthode pratique 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, procédez comme suit:

override init(frame: CGRect) {
    super.init(frame: frame)
    connectNibUI()
}
1
Josh O'Connor

Et comment avez-vous initié votre vue du contrôleur? Comme ça:

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

En supposant que vous ayez essayé les étapes de dépannage standard pour connecter IBOutlets, essayez ceci: 

Apparemment, vous devez désactiver awake of 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
ScottyBlades