UIViewController with Nib File and Inheritance

蓝咒 提交于 2019-12-21 16:52:26

问题


I'm trying to do something really tricky and I'm still stuck at a point. I'm attempting to instance an UIViewController with a Nib file inherited from an other UIViewController with an other Nib file.
The problem is when I instantiate my son UIViewController .

// SonViewController
- (id)initWithNibName:(NSString *)nibNameOrNil 
                bundle:(NSBundle *)nibBundleOrNil
{
    if ((self = [super initWithNibName:nibNameOrNil 
                                bundle:nibBundleOrNil])) {
        // Custom initialization.
    }
    return self;
}

The init method initWithNibName:bundle: should call the super class but it only call its own nib file. In the super class, I tried to override the initWithNibName:bundle: method and put the nibName myself like that :

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

It only init and display the Mother Class and its IB Object. I understand why but I begin thinking it is impossible to do what I want. Any suggestion ?

Edit:
I would use my SonViewController just like that :

SonViewController *son = [[SonViewController alloc] 
                      initWithNibName:@"SonViewController" bundle:[NSBundle mainBundle]];

[self.navigationController pushViewController:son animated:YES];
[son release];

It should display son and mother IB Object...

Regards,
kl94


回答1:


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.




回答2:


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


来源:https://stackoverflow.com/questions/4753742/uiviewcontroller-with-nib-file-and-inheritance

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!