views:

67

answers:

3

Hi,

I have a situation, I have created two different nibs, one in Portrait Mode and other in Landscape mode. I had lots of designs in the view so, i had to opt for two different nibs. Now, I want to toggle the nibs as the interface rotates in the

common viewController

so that I can retain the filled values and the state of the controls I have in the view.

Right now I am using

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Override to allow orientations other than the default portrait orientation.
if(interfaceOrientation == UIInterfaceOrientationLandscapeLeft || interfaceOrientation == UIInterfaceOrientationLandscapeRight ){
    [self initWithNibName:@"LandscapeNib" bundle:nil];
}else if(interfaceOrientation == UIInterfaceOrientationPortrait || interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown){
    [self initWithNibName:@"PortraitNib" bundle:nil];

}


return YES;

}

but it doesn't changes the Nib, it shows the initial loaded nib. May I guess it is loading but not showing because initial nib is already showing, is not removed. I am not able to find the solution of working with multiple nibs with a common view controller so that I can easily handle the functionality of the controls ?

+1  A: 

You can't init self again once self has already been init'ed.

When rotating, you will need to:

  1. Use loadNibNamed:owner:options: to load the nib by hand into an NSArray. (See the documention).
  2. Set self.view to the object at index 0 of that array.
Jon Rodriguez
Even when this might work, I do not recommend replacing controller's view. It sounds dirty, introducing fragile situation where it becomes easy to make mistakes in properly releasing and retaining objects.
Michal
Actually replacing the controllers view will be much better if the user is expected to rotate the device again. It doesn't use that much memory, plus rotating will be quicker. Besides if both views are class objects they can be deallocated and released with the view controller.
MishieMoo
+2  A: 

shouldAutorotateToInterfaceOrientation: should simply return with a YES or a NO. In my experience, its not a good idea to do any extended processing here. From the docs:

Your implementation of this method should simply return YES or NO based on the value in the interfaceOrientation parameter. Do not attempt to get the value of the interfaceOrientation property or check the orientation value reported by the UIDevice class. Your view controller is either capable of supporting a given orientation or it is not.

A better place to load your nibs in response to a device rotation would be

willRotateToInterfaceOrientation:duration: or didRotateToInterfaceOrientation:

TomH
A: 

You should create a special view-controller for landscape mode, and present it modally when device rotates. To be notified when device rotates, register for UIDeviceOrientationDidChangeNotification notifications.

For such complex views that need to be presented differently in portrait and landscape, this is recommended way of implementing it by Apple. Read here for more details:

http://developer.apple.com/library/ios/#featuredarticles/ViewControllerPGforiPhoneOS/BasicViewControllers/BasicViewControllers.html#//apple_ref/doc/uid/TP40007457-CH101-SW26

Here's a snippet from Apple's documentation. Register for notifications in your init or awakeFromNib:

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

and in orientationChanged present your landscape view-controller modally, or dismiss it, all according to current rotation:

- (void)orientationChanged:(NSNotification *)notification
{
    UIDeviceOrientation deviceOrientation = [UIDevice currentDevice].orientation;
    if (UIDeviceOrientationIsLandscape(deviceOrientation) &&
        !isShowingLandscapeView)
    {
        [self presentModalViewController:self.landscapeViewController
                                animated:YES];
        isShowingLandscapeView = YES;
    }
    else if (deviceOrientation == UIDeviceOrientationPortrait &&
             isShowingLandscapeView)
    {
        [self dismissModalViewControllerAnimated:YES];
        isShowingLandscapeView = NO;
    }
}
Michal