1
votes

I've got a simple app with two UIViews, the larger one is created through interface builder, the smaller one programmatically:

Portrait

In Portrait when running on the retina ipad simulator the larger view is taller than the screen. On non-retina ipad it's the correct height. Same on 4 inch iPhone and 3.5 inch iPhone.

However when you rotate the device:

Landscapre

The larger view no longer fills the screen.

I've been iterating on settings the sizes programmatically for so long I don't know which way it up. This is a very simple version of what I've been trying:

  -(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInt
                               duration:(NSTimeInterval)duration {

    CGRect screenBounds = [[UIScreen mainScreen] bounds];
    self.webView.frame  = screenBounds;
}

I've had additional math to cut the height of the larger view by the height of the smaller view, which works -- but I still can't resolve the lack of filling out the screen or the fact that on the retina ipad the height of the larger control is too tall.

Am I getting the size from the wrong place? Is there a way to programmatically tell how tall the statusbar is? Or do I just need to hard code in the 20 pixels?

edit:

Slight progress. Using this:

-(void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
        CGRect screenBounds = [[UIScreen mainScreen] bounds];
        self.webView.frame  = CGRectMake(0, statusBarHeight, screenBounds.size.width, screenBounds.size.height - (smallView.size.height + statusBarHeight));
}

The status bar is not covered now without hard coding the height of the status bar. Except on a retina ipad -- then the height of the status bar appears as a gap between the larger view and the smaller view. The larger view still appears to extend beyond the top of the screen seems like by an amount larger then the status bar height. In Landscape the larger view still doesn't fill the width of the screen. Still scratching my head.

edit 2: I think this issue might be related to this being an Universal app, so the bounds are always being reported as 480x320. I know how to pull down the scaling for the screen but that doesn't get me to the correct dimensions.

3

3 Answers

0
votes

The problem you have is that when willRotateToInterfaceOrientation is called, it hasn't rotated yet so you are reading the old bounds. I think you want didRotateFromInterfaceOrientation. This post is helpful in best practices in this situation.

For the status bar, I use this macro:

#define statusBarHeight (([UIApplication sharedApplication].statusBarFrame.size.height < [UIApplication sharedApplication].statusBarFrame.size.width) ? [UIApplication sharedApplication].statusBarFrame.size.height : [UIApplication sharedApplication].statusBarFrame.size.width)
0
votes

Rotation handling in iOS needs some rethinking, but for me, I always set new sizes in -(void)viewDidLayoutSubviews because I can be sure new sizes have been assigned to frames.

0
votes

I agree with "M. Porooshani".

by the way if you need a very custom layout go on using heavily viewDidLayoutSubviews and similar, but for simple cases far better to let constraints do the job. Calcs and layout in code can be very hard.