Propriétés de l'IBOutlet nul après une vue personnalisée chargée à partir de xib
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
}
}
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)
}
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()
}
et comment avez-vous initié votre vue depuis le contrôleur? Comme ceci:
var view = CustomKeyboard.keyboard()
self.view.addSubview(view)
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
}