user1686342
user1686342

Reputation: 1345

Why does custom xib require UIView property

I followed the tutorial outlined here to load a custom xib in my view controller.

The class of the xib inherits from UIView but also needs a property view:

 @interface MYBannerView : UIView
 @property (nonatomic, weak) IBOutlet UIView *view;
 @end  

I find it strange that it needs this, as its like having a view within a view which seems redundant. Is there any particular reason for this?

Edit

I followed this tutorial here which outlines this:

http://www.maytro.com/2014/04/27/building-reusable-views-with-interface-builder-and-auto-layout.html

Upvotes: 0

Views: 127

Answers (2)

JAL
JAL

Reputation: 42449

The author of that tutorial is using the view outlet to load the view from the xib when MYBannerView is initialized programatically

- (instancetype)initWithCoder:(NSCoder *)aDecoder
{
    self = [super initWithCoder:aDecoder];
    if (self) {
        NSString *className = NSStringFromClass([self class]);
        self.view = [[[NSBundle mainBundle] loadNibNamed:className owner:self options:nil] firstObject];
        [self addSubview:self.view];
        return self;
    }
    return nil;
}

Anything created in Interface Builder will not be loaded with a programatic init. loadNibNamed loads the UI from the xib.

If you want to override initWithFrame: to load the UI elements from the xib, your init method would look something like this:

- (instancetype)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame]; // initialize your objects

    if (self) {
        [[NSBundle mainBundle] loadNibNamed:NSStringFromClass([self class]) owner:self options:nil]; // load your view from IB
    }

    return self; // return the view with all of the IB UI loaded
}

Upvotes: 0

nsinvocation
nsinvocation

Reputation: 7637

No, your UIView subclass doesn't need an outlet to the view to be functional. In fact, using self you have access to the view itself. What about tutorial: when author added view A (let's call it so) on MYViewController's view, he set view A class to be MYBannerView. Running app won't show anything because MYBannerView xib wasn't loaded and didn't replaced content from view A. So author loads this xib in initWithCoder, set outlet using value returned by loadNibNamed: and adds view loaded from MYBannerView to view A. The process is a little bit messy but it works.

Upvotes: 0

Related Questions