Trying to load a nib from interface builder

880 views Asked by At

I have a UIView based class that has its own XIB. Lets call this class MyClass. So I have MyClass.xib, MyClass.h and MyClass.m.

I have a UIView object on storyboard and I set that object's class to MyClass.

I created a new UIView XIB and inside the XIB, I changed the File Owner's class to MyClass. I don't know if I have to do more connections inside the XIB.

What I want is this: the storyboard loads MyClass.m and that loads MyClass.xib, for that reason I have this init code:

- (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;
}

The problem is that this code gets in an infinite loop. I guess the loadNibNamed call initWithCoder: again and the app crashes.

How do I do that? Why the loop and is there any more connections that have to be made inside the xib?

3

There are 3 answers

0
Duck On BEST ANSWER

I have tried all answers but this is the only code that worked, after several trials:

- (instancetype)initWithCoder:(NSCoder *)aDecoder
{
  self = [super initWithCoder:aDecoder];

  if (self.view == nil) {
    NSBundle *mainBundle = [NSBundle mainBundle];
    [mainBundle loadNibNamed:@"MonthDayPicker" owner:self options:nil];

    [self addSubview:self.view];
    return self;

  }

  return nil;
}
0
Shankar BS On

lets do like below

initiate it on awakeFromNib method for example

in MyClass.m file

- (instancetype)initWithFrame:(CGRect)frame
{
  self = [super initWithFrame:frame];
  if(self)
  {
      //set up hear
  }
  return  self;
}

- (instancetype)initWithCoder:(NSCoder *)aDecoder
{
  self =   [super initWithCoder:aDecoder];
  if(self)
  {

  }
  return self;
}


- (void)awakeFromNib
{
   [super awakeFromNib];
   //set up hear
   NSString *className = NSStringFromClass([self class]);
   UIView *view = [[[NSBundle mainBundle] loadNibNamed:className owner:self options:nil] firstObject];
  [self addSubview:view];
}
4
Ewan Mellor On

Using self.subviews.count == 0 breaks the loop, like this:

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