Unable to load two nib (.XIB) for Single ViewController class in Xcode 4.5 [duplicate]

末鹿安然 提交于 2019-12-04 13:59:00
Leeloo Levin

I suggest you do something like this instead:

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    if([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone){
        if([UIScreen mainScreen].bounds.size.height == 568.0)
        {
            //Use iPhone5 VC
            self = [super initWithNibName:@"RootViewController-568h" bundle:nibBundleOrNil];
        }
        else{
            //Use Default VC
            self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
        }
    }
    return self;
}

That is if your RootViewController is named just that. And by doing it this way you save yourself from future crashes if they should decide to add another size of an iPhone/iPod. As you are using two if statements, if neither is true it will crash the app and is really not good coding.

A good practice is to always try and think ahead and plan for the future, if they should release another screen size it wouldn't look good but would at least not crash.

The obvious problem I see from your description is that you set the custom class to "RootViewController" in your nib, but you are actually instantiating a "UIViewController" in your code.

What you should have done is:

viewController3 = [[[RootViewController alloc] initWithNibName:@"RootViewController" bundle:nil] autorelease];

Otherwise, when the runtime loads your nib, and is trying to set up those RootViewController specific outlets in your nib, the runtime won't be able to find those in a vanilla UIViewController, and so crashes.

I don't think that you've to use two different .xib's for iPhone5 & iPhone4, 4S etc. If you want to change the sizes of your images, labels, buttons etc., that's why Spring and Structs are used for. You can also set the sizes programmatically by using the code you've written in your question (in your .m files....... )

I also have done that mistake before. When i used to run the program, i always came up with the error

*** Terminating app due to uncaught exception 'NSInternalInconsistencyException',
 reason: '-[UIViewController _loadViewFromNibNamed:bundle:] loaded the "View" nib but
 the view outlet was not set.' *** First throw call stack:(0x1c93012 0x10d0e7e 0x1c92deb 
0xf58c8 0xf5dc8 0xf5ff8 0xf6232 0x453d5 0x4576f 0x45905 0x4e917 0x2b7f 0x12157 0x12747 
0x1394b 0x24cb5 0x25beb 0x17698 0x1beedf9 0x1beead0 0x1c08bf5 0x1c08962 0x1c39bb6 
0x1c38f44 0x1c38e1b 0x1317a 0x14ffc 0x25fd 0x2525 0x1)libc++abi.dylib: 
terminate called throwing an exception

This is because " nib outlet was not set"

So, i think you should either use Springs and structs or do programmatically..

I would recommend you to :

use story board, instead of XIB files when you instantiate a VC, ex:

    myVC* vc = [self.storyboard instantiateViewControllerWithIdentifier:@"myVCStoryBoardID"];

[self.navigationController pushViewController:vc animated:YES];  

This helps keep VC design under the same roof, and to use powerful features of storyboarding.

Then to check that Auto-layout is active on your story board controllers, and insure that the constrains on one, say, label, map to the boundary of other elements (very important), above and below. This materialises by dotted blue lines when you move it. In most case, the run-time will be able to align everything, regardless of screen height.

I understand that there might be some nasty edge cases in this regards, so you might have to adjust stuff manually. Unless you have complex graphics, it's always possible to work with Y coordinate in the [0,1] interval, and once you have to set a frame, use [[UIScreen mainScreen] bounds].size to get the appropriate value, rounded to the nearest integer.

If all the above fails, then you might have to create separate VC, but in my view, that's not really what the SDK is intended for.

good luck!

MayurCM

Wow, I was such a fool, I didn't realise that I wasn't loading the Nib Properly. Only thing I was wrong with is This line of code

I wrote viewController3 = [[[UIViewController alloc] initWithNibName:@"RootViewController5" bundle:nil] autorelease]; instead of

 [[NSBundle mainBundle] loadNibNamed:@"RootViewController5" owner:self options:nil];

So My Final code is look like this and Works absolutely fine

if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
    {
        CGSize result = [[UIScreen mainScreen] bounds].size;
        if(result.height == 480)
        {
            // iPhone Classic
            [[NSBundle mainBundle] loadNibNamed:@"RootViewController" owner:self options:nil];
        }
        if(result.height == 568)
        {
            // iPhone 5
            [[NSBundle mainBundle] loadNibNamed:@"RootViewController5" owner:self options:nil];
        }
    }

Thanks to this link Link to the right Answer

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