Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Landscape only iPhone app with multiple nibs

I'm developing an iPhone application that has several nibs, and should be landscape only.

The application is set to start in landscape mode via its Info.plist file.

I have two view controllers: FirstViewController and SecondViewController.

For each of these I have a nib file, where the view is in landscape. Both view controllers are added to my MainView nib as outlets, and their views are lazily initialized.

When the application loads, the first view displays in landscape, as expected. However, when I switch to the second view, the device (or simulator) remains in landscape, but the view is rotated, as if the device were in portrait mode, braking my interface.

In both UIViewController classes I have the following code:

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    return interfaceOrientation == UIInterfaceOrientationLandscapeRight;
}

and to switch views, in my app delegate I'm doing:

[viewController.view removeFromSuperview];
[window addSubview:secondViewController.view];

where viewController and secondViewController are the two outlets where the view controllers are connected.

This is how the second view looks in IB: alt text http://img27.imageshack.us/img27/4898/picture1ni.png

and this is how it looks in the simulator: alt text http://img402.imageshack.us/img402/4866/picture2wt.png

Why is that the second view is displaying in landscape but with the interface rotated?

I wouldn't like to deal with transform properties, since that seems overkill.

like image 562
pgb Avatar asked Dec 11 '09 22:12

pgb


1 Answers

I starred this question hoping someone would give you an insightful response and I'd learn something.. sadly I'm afraid that you might need to use transforms to get this to work properly. Here's the code I've been using lately to solve the problem:

- (void)forceLandscapeForView:(UIView *)theView {
  theView.transform = CGAffineTransformMakeRotation(degreesToRadian(90));
  theView.bounds = CGRectMake(0, 0, 480, 320);
  theView.center = CGPointMake(160, 240);
  [theView setNeedsLayout];
  [theView setNeedsDisplay];
}

Then when you're adding your new view, check the current orientation and if necessary force the rotation:

if (!UIDeviceOrientationIsLandscape([UIDevice currentDevice].orientation)) {
  [self forceLandscapeForView:_activeViewController.view];
}

Then of course you'll want to respond appropriately to shouldAutorotateToInterfaceOrientation in each of your view controllers:

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
  return UIInterfaceOrientationIsLandscape(interfaceOrientation);
}

I would love to hear about alternate solutions if this isn't all necessary. There is also one caveat I've noticed with this setup: if you have a transition between views, and you rotate the phone during that transition, it's possible for the views orientations to get flipped or "stuck" on the wrong landscape orientation, such that you need to turn the phone over (landscape-right vs landscape-left) as you navigate between views.

like image 91
pix0r Avatar answered Oct 31 '22 05:10

pix0r