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 ?
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;
}
}
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:
You can't init self again once self has already been init'ed.
When rotating, you will need to:
- Use
loadNibNamed:owner:options:
to load the nib by hand into an NSArray. (See the documention). - Set self.view to the object at index 0 of that array.
I needed to do the same for my own application and finally ended up with a specific UIAutoRotateView class that will handle that for you.
see explanation here
Hope this helps.
精彩评论