IOS 9 changed view loading mode

I noticed a change in how iOS 9 loads / displays views compared to previous versions of iOS. Here's the 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 is the same for iOS 9

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

Note that in the viewWillAppear method viewWillAppear iOS 9 cannot update origin from self.view.frame .

This causes certain problems in my application, for example, initially looking positions.

Does anyone know if it is intended or is it a defect? And maybe a quick fix?

+5
source share
2 answers

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

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

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

I am using a combination of viewWillAppear and viewWillLayoutSubviews along with a new instance variable to replicate the behavior of pre-iOS 9 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]; } } 
+1
source

you can handle swizzling viewWillAppear :, and use screen borders

 - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; self.view.frame = [UIScreen mainScreen].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; }
- (void)viewDidLoad:(BOOL)animated { [super viewDidLoad:animated]; self.view.frame = [UIScreen mainScreen].bounds; } 
0
source

Source: https://habr.com/ru/post/1232204/


All Articles