viewWillTransitionToSize and wrong navigationBar and statusBarFrame heights
Asked Answered
A

1

6

I am trying to get the visible drawing area for a subclass of GLKViewController. In iOS 7, I would determine the orientation and then adjust [UIScreen mainScreen].bounds.size accordingly. Then I would subtract the navigationBar and statusBarFrame heights and voila! - the actual size of my drawing area.

Now I'm trying to update for iOS 8 with viewWillTransitionToSize, however when I rotate the device (I have UIInterfaceOrientationMaskAll on), the size that is passed is wrong. In fact, the width is correct for the view, but not the height (which involves the navbar and statusbar heights).

I've seen a couple of questions on SO that relate but nothing that actually deals with this issue, at least nothing that helped me.

This doesn't seem to me to be doing anything interesting, correct me if I'm wrong:

- (void)viewWillTransitionToSize : (CGSize) size
       withTransitionCoordinator : (id<UIViewControllerTransitionCoordinator>) coordinator
{
    [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];

    NSLog(@"size changed : orig(%f,%f) mainScreen(%f,%f)", size.width, size.height, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height);

    [self updateViews:size];
}

outputs for transitioning to landscape:

size changed : orig(568.000000,256.000000) mainScreen(320.000000,568.000000)

where the height passed from viewWillTransitionToSize appears to be:

320 - (2*32) = 256

and then the next rotation to portrait:

size changed : orig(320.000000,536.000000) mainScreen(568.000000,320.000000)

where the height passed from viewWillTransitionToSize appears to be:

568 - 32 = 536

32 happens to be the height of the navbar in landscape mode (if that means anything).

So my questions are: how does viewWillTransitionToSize get this size? How does it take into account the extra bars that change sizes or disappear depending on the orientation? And most importantly, why is it using these incorrect heights?

Ammonium answered 24/3, 2015 at 21:8 Comment(1)
this is the same issue i'm dealing with now - i get exactly the same numbers as you are getting when my screen rotates, with the same discrepancy (32 or 64 points). The issue for me is that I am using the 'size' argument to get the new view height and width and then using those numbers to calculate a subview size.Helaine
P
13

When looking at view frame sizes viewWillTransitionToSize:withTransitionCoordinationar:, you will likely get the frames before the update.

Better use animateAlongsideTransition:completion: inside this method:

- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator
{
    [super viewWillTransitionToSize:size
          withTransitionCoordinator:coordinator];


    [coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> context)
    {
          //update views here, e.g. calculate your view
    }
                                 completion:^(id<UIViewControllerTransitionCoordinatorContext> context)
     {
     }];
}
Pneuma answered 24/3, 2015 at 21:14 Comment(4)
Yes - thanks so much worked great! I still don't quite understand how viewWillTransitionToSize works though. Why would I get frames from before the update when the size indicated in the parameters is the size being transitioned to? Am I missing something obvious? The size after the transition is definitely not an old frame, but it's not the right frame either.Ammonium
I encountered exactly the same problem as you describe. The strange thing is: when the devices rotates from landscape right to landscape left, the correct frame is provided. The problem only occurs when transitioning from landscape to portrait and vice versa.Mulderig
That is because when rotation between portrait and landscape (or vice versa) the new height of the bars is not yet incorporated in the size parameter of viewWillTransitionToSize. But landscape right and landscape left use the same navigationbar and toolbar height, so in that case there is no need to wait until these bars have been resized. Objective C is full of such tricky business, where you need to use completion blocks or dispatch functions to get the timing right. Far from trivial, and easy to overlook.Ululate
thank you I was having issue with incorrect bounds until I found your answer!Hydrothermal

© 2022 - 2024 — McMap. All rights reserved.