iOS 9 changed view load behaviour
Asked Answered
H

2

6

I have noticed a change in how iOS 9 loads/displays views compared to previous versions of iOS. Here's an output of self.view.frame in iOS 8.4

viewDidLoad {{0, 0}, {320, 504}}
viewWillAppear {{0, 64}, {320, 504}}
viewDidAppear {{0, 64}, {320, 504}}

And here's the same for iOS 9

viewDidLoad {{0, 0}, {320, 504}}
viewWillAppear {{0, 0}, {320, 504}}
viewDidAppear {{0, 64}, {320, 504}}

Notice that in viewWillAppear method iOS 9 fails to update the origin of self.view.frame.

This causes certain issues in my app such as views initially being position incorrectly.

Does anyone know if it's intended or it's a defect? And perhaps a quick fix?

Houselights answered 24/9, 2015 at 16:14 Comment(8)
Why would this change be a problem for you? Subviews should be positioned based on the bounds, not frame, of their parent view. That won't be different here.Absolutism
Good point, only I'm handling the position of a UITabBar (showing in some screens, hiding in others), which is not a subview of self.view. Besides, iOS 9 fails to update view size as well as origin.Houselights
The output you show indicates that the view size is updated. It's 504 in both versions of iOS.Absolutism
On another screen I have viewDidLoad {{0, 0}, {600, 536}}, viewWillAppear {{0, 0}, {600, 536}}, viewDidAppear {{0, 64}, {320, 504}} for iOS 9Houselights
BTW, your first comment led me to try and use [[UIScreen mainScreen] bounds] instead of relying on self.view.frame. This indeed helped me avoid the negative effects of this change in iOS 9, so thanks.Houselights
Don't use UIScreen as your application doesn't allows fill the screen as in the case of slide over and split view on iPad.Notornis
Is it safe to use for iPhone-only though? If not, what is an alternative?Houselights
You should be using self.view.bounds to position your subviews, not self.view.frame.Cavie
P
2

I found the same change in iOS 9 versus previous iOS versions: in viewWillAppear, self.view.frame and self.view.bounds only show the default size used in the nib instead of the size actually used at runtime. This means if, for example, your nib has a default width of 320 but you run it on an iPhone 6, the width will be incorrectly reported as 320 instead of 375.

You could use [[UIScreen mainScreen] bounds], as suggested in the comments to the question, but that would only work if your views always fill the screen. If you have a split-screen design on an iPad and you need to know the actual display width of an individual view, it is not available in viewWillAppear.

You could use viewWillLayoutSubviews instead of viewWillAppear, because the frame and bounds are correctly set at that point. However, this is not called every time a view appears, only when it first appears, so your app behavior will change slightly.

I'm using a combination of viewWillAppear and viewWillLayoutSubviews, along with a new instance variable, to replicate the pre-iOS 9 behavior in iOS 9:

@synthesize sizingReady;

- (void)viewDidLoad {
    [super viewDidLoad];

    // set a flag telling us whether the view size is available
    // this is needed in iOS 9 because the view size isn't updated in viewWillAppear yet
    self.sizingReady = FALSE;
}

- (void)viewWillAppear:(BOOL)animated {
    // don't do anything until the view size is available, which doesn't happen until viewWillLayoutSubviews in iOS 9
    if (!self.sizingReady) {
        return;
    }

    [super viewWillAppear:animated];

    // your code goes here
}

- (void)viewWillLayoutSubviews {
    [super viewWillLayoutSubviews];

    if (!self.sizingReady) {
        self.sizingReady = TRUE;
        [self viewWillAppear:TRUE];
    }
}
Phenocryst answered 14/10, 2015 at 18:53 Comment(0)
E
0

you can method swizzling viewWillAppear: , and use screen bounds



- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];

    self.view.frame = [UIScreen mainScreen].bounds;
}


or



- (void)viewDidLoad:(BOOL)animated {
    [super viewDidLoad:animated];

    self.view.frame = [UIScreen mainScreen].bounds;
}


Ed answered 27/10, 2015 at 16:14 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.