3
votes

I'm interested in having a UIViewController that supports all orientations and cleanly uses two xib files to set up its subviews.

One possibility seems to be to use NSBundle's loadNibNamed: method to load a new view hierarchy at each rotation, but this seems inefficient, and could have unfortunate side effects. For example, after reloading from a nib file, all my views would lose their previous state, such as adding text to a text field, etc.

Is there a better way to do this?

2
Is there a specific reason your interface has to be different enough to use 2 xibs between portrait and landscape? Using the grow/attach autosizing settings in interface builder you can almost always have your UI auto-rotate appropriately. If you absolutely have to have this I'd have both loaded at once and then during rotation swap the views out. - slycrel
Considering the significant change in aspect ratio, I think it's very reasonable to choose significantly different layouts per orientation. - Tyler
I agree. Old post I am commenting on here but I've been searching the entire day for the proper solution for this and have not found one. It IS absolutely appropriate to have a landscape view that is VERY different than a portrait view. Take the stocks app for example. It shows a graph in landscape mode! I don't know why every says that you should not show a different view and to constantly rely upon auto-resizing. Auto-resizing to me is a cop-out. A landscape view is almost an entirely new environment and should have a design specific to it - perhaps other useful features. - Christopher
(continued) The only exception that I see fit for autoresizing in the iPhone are tables. Tables can simply be resized. - Christopher

2 Answers

3
votes

After some more research, I was not able to find an elegant solution to this. Because re-loading elements from a xib file at each rotation seemed slow and eliminated any dynamic view-based data, I switched over to a code-based setup (i.e. no more xib files).

I decided to create a method like this:

// This is for an iPad root-level view controller.
- (void)setupForOrientation:(UIInterfaceOrientation)orientation {
  if (UIInterfaceOrientationIsPortrait(orientation)) {
    CGRect bounds = CGRectMake(0, 0, 768, 1004);
    bkgImageView.frame = bounds;
    // Other view positioning for portrait.
  } else {
    CGRect bounds = CGRectMake(0, 0, 1024, 748);
    bkgImageView.frame = bounds;
    // Other view positioning for landscape.
  }
  [self drawBackgroundForOrientation:orientation];
}

This method is called from the shouldAutorotateToInterfaceOrientation: method, and handed the new orientation.

1
votes

Instead of calling your function from shouldAutorotateToInterfaceOrientation, where you just need to say YES or NO, you should really do your stuff in delegate functions like willRotateToInterfaceOrientation which is meant to do things like what you are doing.