IBOutlet isn't connected in awakeFromNib

*爱你&永不变心* 提交于 2019-12-04 22:18:07
ashack

There is a very good answer to this question here: Accessing View in awakeFromNib?

Long story short, the view may be loaded in awakeFromNib, but its contents are loaded lazily, which is why you should use viewDidLoad instead of awakeFromNib for what you are trying to achieve.

Sethmr

For anyone finding this looking for the appropriate answer in Swift 4, here you go.

override func awakeAfter(using aDecoder: NSCoder) -> Any? {
    guard subviews.isEmpty else { return self }
    return Bundle.main.loadNibNamed("MainNavbar", owner: nil, options: nil)?.first
}

Although, I found the real secret to be that you don't subclass the main view of a .xib file. Instead make the file owner the class you want it to be and add the Nib like so inside of the classes init:

let bundle: Bundle = Bundle(for: type(of: self))
let nib: UINib = UINib(nibName: "<Nib File Name>", bundle: bundle)
if let view = nib.instantiate(withOwner: self, options: nil).first as? UIView {
    view.frame = bounds
    view.autoresizingMask = [.flexibleWidth, .flexibleHeight]
    view.translatesAutoresizingMaskIntoConstraints = true
    addSubview(view)
}

I was having this problem and like you the other articles didn't apply. I had a ViewController, which had its own view. In that ViewController's .xib file I put a view and gave it the class of CustomView. This would work great except for the fact that CustomView was defined in its own .xib file, so naturally in awakeFromNib all the IBOutlets were nil. This is because there is no way in interface builder to link .xib files together. So when my ViewController's view gets put on screen it tries to instantiate CustomView, rather than loading the CustomView.xib file.

There is a work around detailed here http://cocoanuts.mobi/2014/03/26/reusable/, but the gist is I had to implement the following in my CustomView class

@implementation CustomView

    - (id)awakeAfterUsingCoder:(NSCoder *)aDecoder
    {
        if (![self.subviews count])
        {
            NSBundle *mainBundle = [NSBundle mainBundle];
            NSArray *loadedViews = [mainBundle loadNibNamed:@"CustomView" owner:nil options:nil];
            return [loadedViews firstObject];
        }
        return self;
    }

@end

Using Swift you can use item inside your custom view after it's set:

class PointsTableViewCell: UITableViewCell {

    @IBOutlet weak var pointsTitleLabel: UILabel! {
        didSet {
            self.pointsTitleLabel.text = "Points"
        }
    }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!