-->

Handling of awakeFromNib for the object that is Fi

2019-08-21 04:02发布

问题:

I know there are many related questions why awakeFromNib is not called when instantiating some view. The message that the certain view is awaken from Nib is sent to the view itself and this message is not delivered to the File's Owner. I saw Why won't my awakeFromNib fire?.

So, what will happen if you create an view's instance whose File's Owner is itself in the xib file?

In other word, you have your own custom view named MyCustomView.swift and MyCustomView.xib. And in the xib file, you set the file's owner to MyCustomView. So, when you create the instance of MyCustomView, does awakeFromNib get called? In my case, the awakeFromNib doesn't seem to be called. However, the view itself is really instantiated. So, to me it is strange that the awakeFromNib is not called.

Could anyone explain this thing?

FYI: I prepared BaseCustomView.swift. BaseCustomView has two init.

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

and

required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        commonInit()
    }

And commonInit() is like this.

private func commonInit() {
        // load custom view's xib
        let bundle = Bundle(for: type(of: self))
        let nib = UINib(nibName: self.className(), bundle: bundle)
        let view = nib.instantiate(withOwner: self, options: nil).first as! UIView
        addSubview(view)

        // make custom view's size the same size with itself
        view.translatesAutoresizingMaskIntoConstraints = false
        let bindings = ["view": view]
        addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[view]|",
            options:NSLayoutFormatOptions(rawValue: 0),
            metrics:nil,
            views: bindings))
        addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|[view]|",
            options:NSLayoutFormatOptions(rawValue: 0),
            metrics:nil,
            views: bindings))
    }

And customView is just the class which overrides this BaseCustomView. In addition, the customView's File's Owner is customView itself.

More EDIT: The custom view class is like this. And actually the awakeFromNib() is not called.

final class MyCustomView: BaseCustomView {

    override func awakeFromNib() {
    // do something
    }

}

回答1:

The "File's Owner" item in a nib is a bit special: it isn't a real object in the archive, as the other items are. It's a placeholder, that's filled in with a preexisting object when the nib is instantiated.

So, the File's Owner is not really being "awoken" from the nib as the other objects are. It's created before the nib is unarchived. Therefore, it doesn't really make sense for it to receive awakeFromNib.



回答2:

Building on Josh and Kazuya's comments, File's Owner in a xib is obviously located under Placeholder and it is exactly that, a placeholder for the compiler to know there's an ivar on that xib that will have an object in memory to connect to once the xib is instantiated. And actually if you leave it blank, the AppDelegate owns it. File's Owner in my opinion is really obsolete nowadays in IB.

In the inspector on the right hand side, if you set File's Owner -> Custom Class -> Class to MyCustomView but don't set Custom Class -> Class of the xib's top-level hierarchy UIView to MyCustomView, then IBOutlet won't be connected and awakeFromNib() won't be called.

Image attached shows where MyCustomView MUST be set in order for any IBOutlets and awakeFromNib() as well as any other methods in MyCustomView.swift to be called