Optimization for newest iPad Pro Simulator

2019-03-27 09:22发布

问题:

I have installed the newest Xcode 7.1 beta and trying to run my project on the iPad Pro Simulator. Everything is right and all of the features work correct.

But I have an issue with the screen size...

On the main screen of application I run the next log:

NSLog(@"%f", self.view.bounds.size.width);

I have 1024 for landscape orientation. But when I create a new application in Xcode 7.1 and run the same code on the main screen I get another value: 1366.

Today I plan to find diffs between project files created in old Xcode (6.4) and newest beta 7.1 using Araxis Merge.

Do you now how to fix this issue for the my old project?

回答1:

I may be way off here, but I was having a similar problem with the iPad Pro simulator: it kept giving me the standard 1024*768 point resolution. After some digging, I realized that I was using the standard iPad launch image (since there is no iPad Pro version in the asset catalog), which restricted my screen to remain 1024*768 points. Once I introduced a launch storyboard, everything fell into place, and my app launched with the correct, 1366*1024 point size.



回答2:

TL;DR: It appears that the view hierarchy is not adjusted for the iPad Pro screen size until viewWillLayoutSubviews: and viewDidLayoutSubviews: is invoked. When this is invoked by the layout system depends on the construction of your view hierarchy.


In updating my app for iPad Pro I'm also seeing similar behavior. Therefore I took a deeper look at the view controller lifecycle events to see what was happening in both my existing project as well as a new project.

For a brand-new project, using a view controller that only has a navigation bar (placed just below the status bar) and a primary view (that takes up the remainder of the space, with auto-layout turned on, in landscape mode a la the following screenshot:

I'm seeing the following output from the console for the view controller lifecycle:

-[ViewController viewDidLoad] self.navigationBar: .frame: {{0, 20}, {1024, 44}}; .bounds: {{0, 0}, {1024, 44}}
-[ViewController viewDidLoad] self.primaryView: .frame: {{0, 64}, {1024, 704}}; .bounds: {{0, 0}, {1024, 704}}

-[ViewController viewWillAppear:] self.navigationBar: .frame: {{0, 20}, {1024, 44}}; .bounds: {{0, 0}, {1024, 44}}
-[ViewController viewWillAppear:] self.primaryView: .frame: {{0, 64}, {1024, 704}}; .bounds: {{0, 0}, {1024, 704}}

-[ViewController viewWillLayoutSubviews] self.navigationBar: .frame: {{0, 20}, {1024, 44}}; .bounds: {{0, 0}, {1024, 44}}
-[ViewController viewWillLayoutSubviews] self.primaryView: .frame: {{0, 64}, {1024, 704}}; .bounds: {{0, 0}, {1024, 704}}

-[ViewController viewDidLayoutSubviews] self.navigationBar: .frame: {{0, 20}, {1366, 44}}; .bounds: {{0, 0}, {1366, 44}}
-[ViewController viewDidLayoutSubviews] self.primaryView: .frame: {{0, 64}, {1366, 960}}; .bounds: {{0, 0}, {1366, 960}}

-[ViewController viewDidAppear:] self.navigationBar: .frame: {{0, 20}, {1366, 44}}; .bounds: {{0, 0}, {1366, 44}}
-[ViewController viewDidAppear:] self.primaryView: .frame: {{0, 64}, {1366, 960}}; .bounds: {{0, 0}, {1366, 960}}

From what I can see here, the view starts out with a width of 1024 points but once 'viewDidLayoutSubviews' is executed, the appropriate size has been determined (1366 points).

In my own project for one screen which is using a split-view controller, I can see similar behavior:

-[XYZViewController viewDidLoad] self.navigationBar: .frame: {{0, 20}, {1024, 44}}; .bounds: {{0, 0}, {1024, 44}}

-[XYZViewController viewWillLayoutSubviews] self.navigationBar: .frame: {{0, 20}, {1024, 44}}; .bounds: {{0, 0}, {1024, 44}}
-[XYZViewController viewDidLayoutSubviews] self.navigationBar: .frame: {{0, 0}, {1366, 44}}; .bounds: {{0, 0}, {1366, 44}}

-[XYZViewController viewWillLayoutSubviews] self.navigationBar: .frame: {{0, 0}, {1366, 44}}; .bounds: {{0, 0}, {1366, 44}}
-[XYZViewController viewDidLayoutSubviews] self.navigationBar: .frame: {{0, 0}, {1366, 44}}; .bounds: {{0, 0}, {1366, 44}}

-[XYZViewController viewWillAppear:] self.navigationBar: .frame: {{0, 0}, {1366, 44}}; .bounds: {{0, 0}, {1366, 44}}

-[XYZViewController viewWillLayoutSubviews] self.navigationBar: .frame: {{0, 0}, {1366, 44}}; .bounds: {{0, 0}, {1366, 44}}
-[XYZViewController viewDidLayoutSubviews] self.navigationBar: .frame: {{0, 20}, {1366, 44}}; .bounds: {{0, 0}, {1366, 44}}

-[XYZViewController viewWillLayoutSubviews] self.navigationBar: .frame: {{0, 20}, {1366, 44}}; .bounds: {{0, 0}, {1366, 44}}
-[XYZViewController viewDidLayoutSubviews] self.navigationBar: .frame: {{0, 20}, {1366, 44}}; .bounds: {{0, 0}, {1366, 44}}

-[XYZViewController viewDidAppear:] self.navigationBar: .frame: {{0, 20}, {1366, 44}}; .bounds: {{0, 0}, {1366, 44}}

In this case, since the view hierarchy is different, viewWillLayoutSubviews: gets called earlier in the view controller lifecycle and the correct size has already been determined by the time viewWillAppear: is invoked. But as you can see, this really depends on your view hierarchy - so I would recommend that you confirm your view hierarchy and then determine the best location to add your resolution-dependent code.



回答3:

If you hard code the frame of any UI elements due to some reasons, you may have to change it for upcoming iPad pro. Because, it has a different screen size (in points) altogether.

If you use auto layout and dynamic frames (e.g. self.view.bounds.size.width), it should just work fine I guess.