Handle orientation change on iPad with one UIViewC

2019-03-15 17:44发布

i'd like to handle orientation change on an iPad application with one UIViewController and two XIBs, let's say MenuView and MenuViewLandscape.

So, in the willRotateToInterfaceOrientation method of the MenuViewController, how can i change XIB without using another controller for the landscape mode ?

I'm using the following code:

if( toInterfaceOrientation != UIInterfaceOrientationPortrait ){
    MenuViewController *landscape = [[MenuViewController alloc] 
                                        initWithNibName: @"MenuViewLandscape"
                                        bundle:nil 
                                    ];        
    [self setView:landscape.view];
}
else {
    MenuViewController *potrait = [[MenuViewController alloc] 
                                     initWithNibName: @"MenuView"
                                     bundle:nil 
                                  ];        
    [self setView:potrait.view];
}

But when i go to landscape view the XIB the landscape view controls are not properly rotated.

2条回答
爷的心禁止访问
2楼-- · 2019-03-15 18:24

Perhaps the answer from Jon Rodriguez here will do what you want:

Want to use muliple nibs for different iphone interface orientations

If you have two UIViewController classes, a base class for portrait mode and a subclass of that for landscape mode, you can put almost all the code in the base class. So that gives you most of the advantages of a single view controller class while also allowing you to use other solutions like this:

Easiest way to support multiple orientations? How do I load a custom NIB when the application is in Landscape?

查看更多
家丑人穷心不美
3楼-- · 2019-03-15 18:28

I'm not sure there are any strange side-effects with this implementation, but try something like this and see if it works for you:

-(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)orientation duration:(NSTimeInterval)duration {
    if (UIInterfaceOrientationIsPortrait(orientation)) {
        [[NSBundle mainBundle] loadNibNamed:@"MenuView" owner:self options:nil];
        if (orientation == UIInterfaceOrientationPortraitUpsideDown) {
            self.view.transform = CGAffineTransformMakeRotation(M_PI);
        }
    } else if (UIInterfaceOrientationIsLandscape(orientation)){
        [[NSBundle mainBundle] loadNibNamed:@"MenuViewLandscape" owner:self options:nil];
        if (orientation == UIInterfaceOrientationLandscapeLeft) {
            self.view.transform = CGAffineTransformMakeRotation(M_PI + M_PI_2);
        } else {
            self.view.transform = CGAffineTransformMakeRotation(M_PI_2);
        }
    }
}

This assumes that the File's Owner in your MenuView and MenuViewLandscape XIBs are both set to MenuViewController and that the view outlet is set in both XIBs as well. All of your outlets should be reconnected properly on rotation when using loadNibNamed.

If you are building for iOS 4, you could also replace the loadNibNamed lines with these:

UINib *nib = [UINib nibWithNibName:@"MenuView" bundle:nil];
UIView *portraitView = [[nib instantiateWithOwner:self options:nil] objectAtIndex:0];
self.view = portraitView;

and

UINib *nib = [UINib nibWithNibName:@"MenuViewLandscape" bundle:nil];
UIView *landscapeView = [[nib instantiateWithOwner:self options:nil] objectAtIndex:0];
self.view = landscapeView;

These assume that the UIView that you want to display immediately follows the File's Owner and First Responder proxy objects in the XIBs.

Then you just need to make sure the views are rotated properly for the interface orientation. For all of the views that are not in the default portrait orientation, rotate them by setting the transform property of the view and using CGAffineTransformMakeRotation() with the appropriate values as shown in the example above.

The rotation alone might solve your issue without the extra loading of the NIBs. However, loading a whole new instance of a MenuViewController and setting its view to the existing MenuViewController's view might cause some strange behavior with lifecycle and rotation events, so you might be safer trying the examples above. They also save you the trouble of having to create new MenuViewController instances when you only need the view from it.

Hope this helps!

Justin

查看更多
登录 后发表回答