I have an app that I want to only work with in Landscape.
For the first time ever, I'm foregoing IB and trying to set up all my views programmatically, so I'm creating a view and adding a bunch of subviews in loadView method:
self.view = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];
// Create a GMSCameraPosition that tells the map to display the
// coordinate -33.86,151.20 at zoom level 6.
GMSCameraPosition *camera = [GMSCameraPosition cameraWithLatitude:-33.86
longitude:151.20
zoom:6];
self.mapView = [GMSMapView mapWithFrame:CGRectZero camera:camera];
self.mapView.myLocationEnabled = YES;
self.mapView.delegate = self;
self.mapView.mapType = kGMSTypeHybrid;
self.mapView.frame = self.view.frame;
[self.view addSubview:self.mapView];
// add the toolbar
UIToolbar* toolbar = [[UIToolbar alloc] init];
toolbar.frame = CGRectMake(0, self.view.frame.size.height - 44, self.view.frame.size.width, 44);
toolbar.barStyle = UIBarStyleDefault;
NSMutableArray* items = [NSMutableArray array];
[items addObject:[[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"location-arrow.png"]
style:UIBarButtonItemStyleBordered
target:self
action:@selector(locateMe:)]];
[items addObject:[[UIBarButtonItem alloc] initWithTitle:@"Tools"
style:UIBarButtonItemStyleBordered
target:self
action:@selector(toolsButtonTapped:)]];
[toolbar setItems:items];
[self.view addSubview:toolbar];
In my project settings, I have disabled both portrait orientations. I also have this in my root view controller:
// Enforce Landscape Orientation
-(NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskLandscape;
}
-(UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return UIInterfaceOrientationLandscapeRight;
}
My problem is that the simulator starts in landscape mode, but all of the views are sized for portrait - so the bottom chunk of my views are below the screen and the right side of my screen is a big empty region.
I tried fixing this by switching the width and height of the application frame in the first line, but then that leaves some empty vertical room on the left edge of the screen for the status bar.
So, what's the correct way of doing what I'm trying to do?
Put this in current viewcontroller // ios 5
// ios6
Put this code Appdelegate .M.....
Instead of using
[[UIScreen mainScreen] applicationFrame]
try using
[[[[[self view] window] rootViewController] view] bounds]
The bounds will represent the width and height correctly in Landscape orientation, because the bounds will take into account the transform (rotation) that has been applied, while the frame will not.
To see what I mean, set a breakpoint, and in the debugger print out the description of the top level view
lldb> po [[[[self view] window] rootViewController] view]
You'll see that the view has a rotation transform and that its frame does not represent the dimensions of the screen in landscape, but represents the dimensions in portrait!
The long way to calculate the correct applicationFrame would be