0

Is there any way to specify nib name such that application automatically pickups corresponding nib for landscape or portrait when there is change in orientation.Like for iphone 4 and iphone 5 there is Default@2x.png and Default-568h@2x.png something like that.If not?,I am trying in app delegate method to addObserver for orientation change and it is working fine but while changing nib in orientationChanged method cause app to crash and produce error as:

 *** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<FRAppDelegate 0xa18bf20> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key __mapView.'

my code is as follows:

 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    // Override point for customization after application launch.


    self.viewController = [[FRViewController alloc] initWithNibName:@"FRViewController" bundle:nil];


    [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
    [[NSNotificationCenter defaultCenter]
     addObserver:self selector:@selector(orientationChanged:)
     name:UIDeviceOrientationDidChangeNotification
     object:[UIDevice currentDevice]];

    self.window.rootViewController = self.viewController;
    [self.window makeKeyAndVisible];
    return YES;
}

- (void) orientationChanged:(NSNotification *)note
{
    UIDevice * device = note.object;
    switch(device.orientation)
    {
        case UIDeviceOrientationPortrait:
        case UIDeviceOrientationPortraitUpsideDown:
        {
           NSArray *nibArray=[[NSBundle mainBundle] loadNibNamed:@"FRViewController" owner:self options:nil];
           [self.viewController setView:[nibArray objectAtIndex:0]];
            NSLog(@"device orientation comes to portrait mode ");
            /* start special animation */
        }
            break;

        case UIDeviceOrientationLandscapeRight:
        case UIDeviceOrientationLandscapeLeft:
        {
            NSArray *nibArray=[[NSBundle mainBundle] loadNibNamed:@"FRViewControllerLand" owner:self options:nil];
            [self.viewController setView:[nibArray objectAtIndex:0]];
            NSLog(@"device orientatino comes to Landscape mode");
            /* start special animation */
        }
            break;

        default:
            break;
    };
}
  • you dont need to load a new nib ? you just need to call a delegate method on orientation change and pass it true. – X-Factor Mar 05 '13 at 06:56
  • please explain i don't understand what you are trying to say –  Mar 05 '13 at 06:57
  • I wanted to know why are you trying to load a new nib ?? – X-Factor Mar 05 '13 at 07:01
  • I have two xib one is for portrait and other is for landscape.It is very hard to change position or sizes of subviews while changing orientation that's why i need it like android.I have already tried the and u have provided me to try.its not working –  Mar 05 '13 at 07:04
  • Ok then i have given you the answer @iDeveloper try it out. Regards – X-Factor Mar 05 '13 at 07:06
  • you are changing orientation I need to load nib on change orientation –  Mar 05 '13 at 07:10

2 Answers2

0
  1. If you really want to load a different nib, you could use:

    [[NSBundle mainBundle] loadNibNamed:@"PageView_iPhone" owner:self options:nil];
    NSArray* nibViews = [[NSBundle mainBundle] loadNibNamed:@"PageView_iPhone"
                                                  owner:self
                                                options:nil];
    PageView_iPhone* myView = [nibViews objectAtIndex:0];
    

Then in some where swap your view with the new view

like

self.view = myView;
  1. Or you can use Quoted By @Javy

During init, I setup my views (create them programatically) and create extra CGPoint's for center positions or CGRect's for frames for each view in the view controller.

After the views are created in init, I call method named layoutViewsForOrientation to set the initial position, passing in the current status bar orientation. When the orientation changes, I use this code:

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    BOOL result = NO;
    if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
        result = (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
    } else {
        result = YES;
    }
    if( result == YES ) [self layoutViewsForOrientation:interfaceOrientation];
    return result;
}
X-Factor
  • 2,067
  • 14
  • 18
  • Now you have both solutions, swap the nib or swap the orientation, both possibilities i have posted.This is best i can help. Regards – X-Factor Mar 05 '13 at 07:13
0

Although this is not the direct solution for loading a nib, i think you are getting that error because your second nib doesn't have an outlet for a UI object (i.e __mapView)set up properly. i.e Wherever you have connected __mapView from the xib, the IBOutlet is not there in that class any more.

Update: This is happening because you are loading the nib keeping FRAppDelegate as the owner ( you are specifying self as the owner.) If you change it to self.viewController, then your exception should go away.

i.e ; instead of :

NSArray *nibArray=[[NSBundle mainBundle] loadNibNamed:@"FRViewController" owner:self options:nil]; 
NSArray *nibArray=[[NSBundle mainBundle] loadNibNamed:@"FRViewControllerLand" owner:self options:nil];

use

NSArray *nibArray=[[NSBundle mainBundle] loadNibNamed:@"FRViewController" owner:self.viewController options:nil];
NSArray *nibArray=[[NSBundle mainBundle] loadNibNamed:@"FRViewControllerLand" owner:self.viewController options:nil];
Rakesh
  • 3,370
  • 2
  • 23
  • 41
  • I have updated the answer to show what is wrong with your code. There maybe better ways to do what you are trying. For that refer the other answers. – Rakesh Mar 05 '13 at 07:43