Свойства IBOutlet nil после пользовательского представления, загруженного из xib

Что-то странное происходит с 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
    }
}

Ответ 1

Это ожидалось, потому что IBOutlet (s) не назначены к моменту вызова инициализатора. Вам не нужен commonInit, просто переопределение awakeFromNib следующим образом:

override func awakeFromNib() {
    super.awakeFromNib()

    print(aButt)
}

Ответ 2

Ваш нить не может быть подключен. Мое решение довольно простое. Где-то в вашем проекте (я создаю класс под названием UIViewExtension.swift) добавьте расширение UIView с помощью этого удобного метода 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)
        }
    }
}

Теперь вы можете вызвать этот метод в любом представлении в методе init, сделайте следующее:

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

Ответ 3

И как вы инициировали свое представление из элемента управления? Вот так:

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