Question

Introduction

This is a rather common question, however I have certain extra points to observe. One of them is that I don't want to make my bars opaque. I like the iOS7 translucent bars.

I have an UIImageView inside a UIScrollView, and I'm trying to set the initial scrollView.zoomScale to fit the image in the screen just like the stock Photos app does. That means: the image should not be cropped and should fill the screen as much as possible.

However for my app this is a bit more complicated as I have visible statusBar, navigationBar and tabBar. I will adopt the solution to hide them until the user touches the screen, but I'm still curious for a solution when hiding is not desirable.

Done so far

I'm currently calculating the zoom based on a relation between the image's height and the view's height:

double heightRelation = self.image.size.height / self.view.frame.size.height;

After applying 1/heightRelation to the scrollView.zoomScale, the image is still bigger than the useful space. Then I found the iOS7 default heights for statusBar (20pt), tabBar (49pt) and navigationBar (44pt) from the documentation and also from:

NSLog(@"status : %f", CGRectGetHeight([[UIApplication sharedApplication] statusBarFrame]));
NSLog(@"tab : %f", self.tabBarController.tabBar.frame.size.height);
NSLog(@"nav : %f", self.navigationController.navigationBar.frame.size.height);

... and after playing a little, I found that the exact combination would be to subtract statusBar and navBar heights from the view's height:

double heightRelation = self.image.size.height / (self.view.frame.size.height - CGRectGetHeight([[UIApplication sharedApplication] statusBarFrame]) - self.navigationController.navigationBar.frame.size.height);

This works great for the Portrait mode, but doesn't for Landscape. I know I could also make a condition to set the zoom according to the orientation but... The code is probably getting unnecessarily ugly.

So I ask you: what's the best method to get the useful height?

P.S.: Interface Builder's option "Adjust Scroll View Insets" has no effect.

Was it helpful?

Solution

Don't use the bars directly. Use the length properties of bottomLayoutGuide and topLayoutGuide of the view controller to determine how much of the view is "wasted" under the bars. These take into account navigation bars, toolbars, status bar, tab bars, etc., and are maintained by the system when the bars are resized (for example, after rotation to landscape on phone/pod idioms).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top