Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Load Nib for UIView used in ViewController in StoryBoard

Tags:

I have a UIView that I want to use in several View Controllers so I created the view (.h/.m) and a nib file for it. In Storyboard view is added as subview to view controller but is not loading the layout as defined in nib.

Is it possible to load the nib for a UIView used within a view controller in a Storyboard?

like image 988
tiltem Avatar asked Jan 15 '14 07:01

tiltem


People also ask

How do you load a nib on a storyBoard?

If you want to load the view from a nib in code you would just instantiate it directly using the same technique. All the subclass does is take the code to instantiate the view from a nib and put it in a hook for the storyboard to use.

Could not load nib in bundle Nsbundle not yet loaded )' with name?

It happens when you rename the nib file. If you have already, create new nib(meaning copy current nib file contents to new nib), delete old nib file and it will solve your problem.


3 Answers

If you ask about seeing your .xib content in Interface Builder when editing Storyboard, it's not possible. But if you need to load it in runtime, it's possible.

  • .h/.m should contain UIView subclass
  • in .xib file you need to set File's owner (Identity Inspector -> Custom Class) with your custom UIView subclass
  • in .h file add @property (strong, nonatomic) IBOutlet UIView* view; and connect your View container from Interface Builder to this field (Ctrl + Click on View and drag connection to above view property in .h
  • connect other subviews to .h
  • in .m file you need to place


- (void)awakeFromNib {
    NSString* nibName = @"Place here your Nib name without extension";
    if ([[NSBundle mainBundle] loadNibNamed:nibName owner:self options:nil]) {
        [self.view setFrame:[self bounds]];
        [self addSubview:self.view];
    }
}

That's all. Move View to Storyboard scene, change Custom Class to your FooView, import .h in View Controller code and use IBOutlets as you want.

Have happy coding

EDIT

I want to notice that according awakeFromNib documentation we should avoid such code in awakeFromNib.

It is recommended that you maintain a one-to-one correspondence between your File’s Owner objects and their associated nib files. Loading two nib files with the same File’s Owner object causes that object’s awakeFromNib method being called twice, which could cause some data structures to be reinitialized in undesired ways. It is also recommended that you avoid loading other nib files from your awakeFromNib method implementation.

like image 130
Anton Gaenko Avatar answered Sep 25 '22 02:09

Anton Gaenko


Name your view ViewInNib, then we have:

  1. ViewInNib.h
  2. ViewInNib.m
  3. ViewInNib.xib

In your storyboard, put a placeholder UIView component in the view controller, remember to set it's class ViewInNib, then in ViewInNib.m:

static BOOL isReplaced = NO;
- (id)awakeAfterUsingCoder:(NSCoder *)aDecoder
{
    if (!isReplaced) 
    {
        isReplaced = YES;
        ViewInNib *replaced = [[[NSBundle mainBundle] loadNibNamed:@"ViewInNib" owner:nil options:nil] lastObject];
        replaced.frame = self.frame;
        replaced.translatesAutoresizingMaskIntoConstraints = NO;
        return replaced;
    }
    isReplaced = NO;
    return self;
}

In this method, we replace real view loaded from nib from view in storyboard. Hope it helps.

like image 22
sunnyxx Avatar answered Sep 24 '22 02:09

sunnyxx


use XXNibBridge:

https://github.com/sunnyxx/XXNibBridge

Super simple to use and works with Swift as well. Full credit goes to @sunnyxx

like image 42
Robert Wagstaff Avatar answered Sep 22 '22 02:09

Robert Wagstaff