Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to load different XIBs for different device orientations for same viewcontroller?

The documentation says that if I want to support both portrait and landscape, I basically have two ways of doing that:

  1. Set up the viewcontroller's view so that the subviews autoresize correctly and make smaller changes programmatically at runtime
  2. If the changes are more substantial, create an alternative landscape interface and push/pop the alternative modal viewcontroller at runtime

I would like to present the info where the layout is substantially different, but logic is the same. Ideally, I would load another XIB for the same viewcontroller, but it does not seem to be an option.

Sounds like #2 is what I need to do, but my problem with that is that it sounds like it would use the standard modalviewcontroller animations that are nothing like the device rotation animation. (Of course, being the lazywebber that I am, I did not test this hypothesis.)

So, how do I load an alternative layout for landscape with the same viewcontroller but different XIB? Should I use the method #2 above and is the rotation animation natural? Or is there some other way?

like image 659
Jaanus Avatar asked Apr 20 '10 21:04

Jaanus


1 Answers

I instantiate my UIView instances in -viewDidLoad: and add them as subviews to the view controller's view property:

- (void) viewDidLoad {
    [super viewDidLoad];

    self.myView = [[[UIView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 280.0f, 210.0f)] autorelease];
    // ...
    [self.view addSubview:myView];
}

I then call -viewWillAppear: to center those subviews:

- (void) viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    [self adjustViewsForOrientation:[[UIDevice currentDevice] orientation]];
}

I also override -willRotateToInterfaceOrientation:duration:

- (void) willRotateToInterfaceOrientation:(UIInterfaceOrientation)newInterfaceOrientation duration:(NSTimeInterval)duration {
    [self adjustViewsForOrientation:newInterfaceOrientation];
}

The -adjustViewsForOrientation: method sets the center CGPoint of various subview objects, depending on the device's orientation:

- (void) adjustViewsForOrientation:(UIInterfaceOrientation)orientation {
    if (orientation == UIInterfaceOrientationLandscapeLeft || orientation == UIInterfaceOrientationLandscapeRight) {
        myView.center = CGPointMake(235.0f, 42.0f);
        // ...
    }
    else if (orientation == UIInterfaceOrientationPortrait || orientation == UIInterfaceOrientationPortraitUpsideDown) {
        myView.center = CGPointMake(160.0f, 52.0f);
        // ...
    }
}

When the view controller is loaded, the UIView instances are created and positioned based on the device's current orientation. If the device is subsequently rotated, the views are re-centered to new coordinates.

To make this smoother, one could probably use a keyed animation in -adjustViewsForOrientation:, so that the subviews more gracefully move from one center to the other. But the above works for me, for now.

like image 112
Alex Reynolds Avatar answered Oct 04 '22 06:10

Alex Reynolds