UIViewController: extendedLayoutIncludesOpaqueBars and scroll view offset

My application view hierarchy is pretty simple: a UINavigationController contains a UITableViewController . The navigation bar of the navigation controller is opaque, which causes some strange insertions of the table view behavior during navigation transitions, which can be seen here:

Problem with navigation insert

To fix this, I set extendedLayoutIncludesOpaqueBars to true on the UITableViewController . This correctly expands the view under the navigation bar, but changes the behavior of the table view contentOffset in a way that I don't quite understand. With this property set to true , the value Y in the table contentOffset reports that it is shifted higher than it should be at the current height of the navigation bar (for example, scrolling the table view 1pt, it reports that its y-offset -63pts).

This made me think that the navigation controller automatically controlled the scroll view of the contentInset , as well as for translucent bars. But I could not see any evidence that the scroll has content inserts set to scrollViewDidScroll() . Even if automaticallyAdjustsScrollViewInsets set to false on the table view controller, the content offset was incorrect, so it doesn't seem to be related to inserts.

Apple's documentation on extendedLayoutIncludesOpaqueBars does not mention the effect on scroll content offset behavior. Changing the contentInset in the table view, unfortunately, does not solve this.

I tried to change the edgesForExtendedLayout table view controller property to make it expand without affecting the scroll view, but it seems like this property is powerless against opaque bars.

Is there any hidden behavior with extendedLayoutIncludesOpaqueBars that causes the scroll content to shift? Or could it be a mistake?

+3
source share
3 answers

Have you tried this?

 if #available(iOS 11, *) { tableView.contentInsetAdjustmentBehavior = .never } 
+2
source

Background information on what is happening ---

extendedLayoutIncludesOpaqueBars essentially says that your look behaves as if the navigation bars are translucent. Your view will begin at the top (bottom) of the navigation panel, and not at the bottom of the panel.

Then the navigation controller sees that you have a scroll view, and automatically inserts it to compensate for the area covered by the panel.

In iOS 10, you can request contentInset and see the top = 64 insert. However, in iOS 11, the contentInset strictly for any custom inputs that you control, you must use the adjustedContentInset , which is the sum of your custom inserts and any safe areas.

 adjustedContentInset - The insets derived from the content insets and the safe area of the scroll view. contentInset - The custom distance that the content view is inset from the safe area or scroll view edges. 

So, offset y -63 makes sense, it's the same as what you saw if your bars were translucent.


The problem you are talking about , which your GIF demonstrates, I think is a mistake (see fooobar.com/questions/1272083 / ... ).

While the JoniVR answer should work, I solved it in my projects by setting extendedLayoutIncludesOpaqueBars = true .

Although this is probably not as important as you decide, extending the layout is better for me than changing the contentInsetAdjustmentBehavior . Setting for never has a wider range of potential effects; you say you never care about a safe area, no matter where the safe area comes from. The safe area may change (for example, during rotation) or if your controller is presented in different contexts / containers (for example, in the tab bar or not).

+2
source

As @beebcon already pointed out , this was a bug (an Apple engineer confirmed on twitter) and should be fixed in iOS 11.2.

first tweet enter image description here

(I apologize that I used images, but it doesn’t disappear if tweets disappear)

+2
source

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


All Articles