UIViewController:extendedLayoutIncludesOpaqueBars和滚动视图偏移量

我的应用程序的视图层次结构非常简单:一个UINavigationController包含一个UITableViewController 。 导航控制器的导航栏是不透明的,导致在导航转换期间表格视图的一些奇怪的插入行为,如下所示:

导航插图问题

为了解决这个问题,我在UITableViewController上设置了extendedLayoutIncludesOpaqueBarstrue 。 这样做正确地扩展了导航栏下面的视图,但以我不太明白的方式更改了表视图的contentOffset的行为。 将此属性设置为true ,表视图的contentOffset的Y值报告它的偏移量应高于导航栏当前高度的偏移量(即滚动table view 1pt,则报告其y偏移量为-63pts)。

这让我觉得导航控制器自动pipe理滚动视图的contentInset ,就像它对半透明酒吧。 但是我看不到有任何证据表明scrollViewDidScroll()中的scroll view有内容插入。 即使在表格视图控制器上将automaticallyAdjustsScrollViewInsets设置为false ,内容偏移也是不正确的,所以看起来与插入无关。

Apple关于extendedLayoutIncludesOpaqueBars的文档没有提及滚动视图的内容偏移的行为。 更改表视图的contentInset不幸的是不能解决这个问题。

我试图改变表视图​​控制器的edgesForExtendedLayout属性强制它扩展而不影响滚动视图,但似乎这个属性是无力对不透明的酒吧。

是否有一些隐藏的行为与extendedLayoutIncludesOpaqueBars滚动视图的内容偏移量的extendedLayoutIncludesOpaqueBars ? 或者这可能是一个错误?

你尝试过吗?

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

正如@beebcon之前指出的那样,这确实是一个bug(苹果工程师在twitter上确认),应该在iOS 11.2中修复。

第一个推特 在这里输入图像说明

(对不起,我使用了图片,但是这样它不会消失,以防止tweets消失)

背景是什么事情

extendedLayoutIncludesOpaqueBars本质上告诉您的视图行为就像导航栏是半透明的。 然后,您的视图的框架将从导航栏的顶部(底部)开始,而不是在栏的底部。

导航控制器会看到您有一个滚动视图,并自动将其插入,以补偿该栏所覆盖的区域。

在iOS 10中 ,您可以查询contentInset并查看top = 64插图。 但是,在iOS 11中, contentInset严格用于您控制的任何自定义插入 – 您应该使用adjustedContentInset ,这是您的自定义插入和任何安全区域插入的总和。

 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. 

所以真的,-63的偏移量是有道理的,如果你的酒吧是半透明的,你会看到同样的结果。


你说的问题 ,你的GIF演示,是我想一个错误(请参阅https://stackoverflow.com/a/46397291/2145198 )。

虽然JoniVR的答案应该工作, 通过设置extendedLayoutIncludesOpaqueBars = true 解决了我的项目

虽然解决这个问题可能不是什么大不了的事情,但是扩展布局对我来说更像是一种更好的做法,而不是改变contentInsetAdjustmentBehavior 。 将其设定为never有更广泛的潜在影响; 你告诉它不要关心安全区域,不pipe安全区域来自哪里。 安全区域可能会改变(如旋转),或者如果您的控制器是在不同的上下文/容器(如标签栏或不)。