Reputation: 11
I'm trying to implement forced portrait / landscape orientation for different sub modes of my app. To do this I have a UINavigationController as the root controller and each sub mode has it's own view controller that are one of either
@interface iosPortraitViewController : UIViewController
or
@interface iosLandscapeViewController : UIViewController
with
-(BOOL)shouldAutorotate;
-(UIInterfaceOrientation)preferredInterfaceOrientationForPresentation;
-(NSUInteger) supportedInterfaceOrientations;
overloaded and set correctly based on the orientation type for each of them. e.g. iosLandscapeViewController::supportedInterfaceOrientations returns UIInterfaceOrientationMaskLandscape.
When the sub mode in the app changes, the corresponding view controller is presented on the root view controller using present / dismissViewController and this forces the orientation to re-evaluate and call the functions in the overloaded view controller classes and orientate itself accordingly.
My problem is that when we switch to landscape, the frame of the sub mode view is offset from the top left corner of the screen which is where it should be (it's a full screen view showing a background pic).
For debugging purposes, if I change the view controller for that sub mode to a iosPortraitViewController the view information is:
size = 480.000000 320.000000
bounds = 0.000000 0.000000 480.000000 320.000000
frame = 0.000000 0.000000 480.000000 320.000000
centre = 240.000000 160.000000
user interaction enabled = 1
hidden = 0
transform = 1.000000 0.000000 0.000000 1.000000 : 0.000000 0.000000
When in landscape mode, which is what it needs to be, the view information is:
size = 480.000000 320.000000
bounds = 0.000000 0.000000 480.000000 320.000000
frame = 80.000000 -80.000000 320.000000 480.000000
centre = 240.000000 160.000000
user interaction enabled = 1
hidden = 0
transform = 0.000000 -1.000000 1.000000 0.000000 : 0.000000 0.000000
The 80, -80 origin of the frame is the problem I'm having - it should be 0,0. (if anyone could point out how it's getting 80,-80 too that would be appreciated - I can see it for X but not Y).
Also notice how the w and h in the frame are swapped around and the transform is a rotation transform - From reading, I'm guessing the UIWindow (which is always in portrait mode) has applied this to the view transform of the root view controller?
What can I do to get around this? I need the frame of the view controller view to be in the correct place (i.e origin at 0,0). I tried hardcoding it but it didn't appear to work and its not a very good solution anyway - I'm much rather understand what's going on and how to fix it properly.
Thanks!
:-)
Upvotes: 0
Views: 433
Reputation: 581
To support an alternate landscape interface, you must do the following:
From apple's guide to Creating an Alternate Landscape Interface
Also from the guide:
@implementation PortraitViewController
- (void)awakeFromNib
{
isShowingLandscapeView = NO;
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(orientationChanged:)
name:UIDeviceOrientationDidChangeNotification
object:nil];
}
- (void)orientationChanged:(NSNotification *)notification
{
UIDeviceOrientation deviceOrientation = [UIDevice currentDevice].orientation;
if (UIDeviceOrientationIsLandscape(deviceOrientation) &&
!isShowingLandscapeView)
{
[self performSegueWithIdentifier:@"DisplayAlternateView" sender:self];
isShowingLandscapeView = YES;
}
else if (UIDeviceOrientationIsPortrait(deviceOrientation) &&
isShowingLandscapeView)
{
[self dismissViewControllerAnimated:YES completion:nil];
isShowingLandscapeView = NO;
}
}
Upvotes: 1