IPhone Landscape-Only Utility-Template Application

iphonelandscape

I'm trying to create an iPhone application that is always in landscape mode, using the Utility application template. Here's what I did:

  • Create a new iPhone application project, using the Utility Application template
  • In Interface Builder, rotate all the views 90 degrees.
  • In Interface Builder, add a label to the middle of the MainView. Stretch it all the way across the view, set the alignment to centered, and set the autosizing springs so that it can stretch horizontally.
  • In Info.plist, add the key "UIInterfaceOrientation" with value "UIInterfaceOrientationLandscapeRight"
  • In the controller classes, change the shouldAutorotateToInterfaceOrientation methods to "return (interfaceOrientation == UIInterfaceOrientationLandscapeRight) || (interfaceOrientation == UIInterfaceOrientationLandscapeLeft);"
  • Run the app.

When I launch my app, it comes up in landscape orientation, but the main view only covers the top half of the display, and it is stretched horizontally. I get the same results in both the simulator and on an actual device. I've seen it with versions 2.2 and 2.2.1 of the SDK.

I have been able to work around the problem by adding the following step to the above:

  • Add "self.view.autoresizesSubviews = NO;" to RootViewController's viewDidLoad method after "[super viewDidLoad];".

If I do this, then it works as expected. But this feels like a hack. Why should this be necessary?

I don't think it is a transformation issue. All elements are drawn in the proper orientation and with the proper scaling. The problem seems to be that the bounds rectangles of the main view gets funky. It looks like the height of the main view is being cut by a little more than half, and the width is being increased by about 50%.

If I do the exact same set of steps using the View-based Application template instead of Utility, then everything works as expected. So I'm pretty sure the problem is specific to how a Utility application manages its views.

Anybody understand what's going on here?

Best Answer

I was going to say that setting this key does not rotate your interface; you still need to lay out your content in landscape mode and do the appropriate rotation using CFAffineTransform - see "Launching in Landscape Mode" in iPhone OS Programming Guide. Going to find the reference for you, I found this comment: "To launch a view controller–based application in landscape mode in versions of iPhone OS prior to v2.1, you need to apply a 90 degree rotation to the transform of the application’s root view in addition to all the preceding steps. Prior to iPhone OS 2.1, view controllers did not automatically rotate their views based on the value of the UIInterfaceOrientation key. This step is not necessary in iPhone OS 2.1 and later, however."

So if you're running pre-2.1, you need to add this code to your viewDidLoad method in your view controller. (Otherwise, can you post some code?)

-(void)viewDidLoad 
// After loading the view, transform the view so that the co-ordinates are right for landscape
// As described in iPhone Application Programming Guide
// Weird, I'm sure this used to be needed, but it doesn't now. The one in CardScrollViewController is needed though.
{
    [super viewDidLoad];

    CGAffineTransform transform = self.view.transform;
    CGPoint center = CGPointMake(kScreenHeight / 2.0, kScreenWidth / 2.0);

    // Set the center point of the view to the center point of the window's content area.
    self.view.center = center;

    // Rotate the view 90 degrees around its new center point.
    transform = CGAffineTransformRotate(transform, (M_PI / 2.0));
    self.view.transform = transform;    
}