olha
olha

Reputation: 2272

How to deal with temporarily incorrect SafeAreaInsets?

I'm working on a nice screen rotation animation in my iOS app. When the screen's size changes, I update the (Metal) model inside it accordingly.

The problem is that I have visual content "jumps" due to the buggy info from the VC's lifecycle events.
I'm not using AutoLayout, but the visual results are the same for both Auto and Manual Layout - only the code differs.

An example: on my iPhone XR in the

    portrait mode: ViewSize = 414x986, SafeAreaInsets = 92, 0, 34, 0
    landscape mode: ViewSize = 800x414, SafeAreaInsets = 44, 0, 21, 0

The values are so strange because it's Photos Extension :)

Now, when the screen is rotated from Portrait to Landscape, it's not done in one transaction, but in multiple steps:

Events log:
1. ViewDidLayoutSubviews: {{0, 0}, {414, 896}} + {92, 0, 34, 0} -> {{0, 0}, {414, 896}} + {92, 0, 34, 0}
2. SafeAreaInsetsDidChange: {{0, 0}, {414, 896}} + {92, 48, 34, 0}
3. ViewDidLayoutSubviews:  {{0, 0}, {414, 896}} + {92, 0, 34, 0} -> {{0, 0}, {414, 896}} + {92, 48, 34, 0}
4. SafeAreaInsetsDidChange: {{0, 0}, {414, 896}} + {44, 0, 21, 0}
5. ViewDidLayoutSubviews:  {{0, 0}, {414, 896}} + {92, 48, 34, 0} -> {{0, 0}, {414, 896}} + {44, 0, 21, 0}
6. ViewWillTransitionToSize
7. ViewDidLayoutSubviews: {{0, 0}, {414, 896}} + {44, 0, 21, 0} -> {{0, 0}, {800, 414}} + {44, 0, 21, 0}
 
Meaning:
1 = view frame + insets for Portrait orientation (before rotation)
2 = incorrect info: `{92, 48, 34, 0}` is invalid insets, valid ones are {92, 0, 34, 0} in Portrait and {44, 0, 21, 0} in Landscape
3 = incorrect info, see 2
4 = correct insets arrived for Lanscape, but ViewSize is still Portrait
5 = incorrect pair ViewSize + SafeAreaInsets, see 4
6 = ViewWillTransitionToSize event arrived, why so late?
7 = finall correct pair ViewSize + SafeAreaInsets

So the question is:

  1. how can we know that in SafeAreaInsetsDidChange only one of the inset side changed, and more sides are about to change?
  2. how can we know that in SafeAreaIViewDidLayoutSubviews SafeAreaInsets are for the new orientation, and ViewSize is still for the old orientation?

I guess it's not possible to get this info from UIKit, but still try :)

Upvotes: 1

Views: 736

Answers (0)

Related Questions