UIViewController with Nib File and Inheritance

左心房为你撑大大i 提交于 2019-12-04 07:14:47

I know this is an old thread, but I just found an incredibly blog post here.

Essentially, you have to iterate through all the views of the parent class and add them as subviews to your child class. Here's how I implemented it in my project:

// ChildViewController.m
- (void)viewDidLoad
{
    [super viewDidLoad];
    [self addSubviewsFromSuperclass];  
}

// ParentViewController.h
- (void)addSubviewsFromSuperclass;   

// ParentViewController.m
- (void)addSubviewsFromSuperclass
{
    UIView *selfView = self.view;
    UIView *nibView = nil;
    @try
    {
        nibView = [NSBundle.mainBundle loadNibNamed:NSStringFromClass([self superclass]) owner:self options:nil][0];
    }
    @catch (NSException *exception)
    {
        NSLog(@"Something exceptional happened while loading nib:\n%@", exception);
    }
    self.view = selfView;
    for (UIView *view in nibView.subviews)
    {
        [self.view addSubview:view];
    }
}

That addSuviewsFromSuperclass method is not my coding. I have to give full credit to the author of the blogpost I mentioned above. Download his example project and you'll find it in his JMViewController.m.

Normally, you should only use a specific nib in the init method, and not the initWithNibName:bundle:, for this reason.

@implementation MotherViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
    if((self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])) {
        //custom initialization
    }
    return self;
}
- (id)init {
    return [self initWithNibName:@"MotherViewController" bundle:nil];
}

Then, to use the default nib for MotherViewController, you just use [[MotherViewController alloc] init];.

As an alternate, you could define a different initializer in MotherViewController for this reason.

@implementation MotherViewController
- (id)_initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
    if((self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])) {
        //custom initialization
    }
    return self;
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
    return [self _initWithNibName:@"MotherViewController" bundle:nibBundleOrNil];
}

Then, use a private category interface to tell SonViewController about this method.

//SonViewController.m
@interface MotherViewController (PrivateInit)
- (id)_initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil;
@end
@implementation SonViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
    if((self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])) {
        //custom initialization
    }
    return self;
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!