translucent与automaticallyAdjustsScrollViewInsets在NavigationContorller+ScrowView的显示问题总结

1、ios7之后的navigationBar的半透明属性translucent默认是YES
1)如果设置为NO,navigationBar也就不再有半透效果,如果ViewController中的 tableView的frame是(0, 0, self.view.frame.size.width, self.view.frame.size.height),做视图布局之后,在视图View中的显示如图:(绿色是tabView,黄色是ViewController.view)


translucent与automaticallyAdjustsScrollViewInsets在NavigationContorller+ScrowView的显示问题总结
文章图片
translucent与automaticallyAdjustsScrollViewInsets在NavigationContorller+ScrowView的显示问题总结
文章图片
从图可以看到,tableView的W-H是跟ViewController.view的一样,屏幕的Screen Bounds的height减掉导航高度才是ViewController.view的高度。此时的tableView的origin=(0,0),同样ViewController.view的orgin=(0,0)都是从Screen Bounds的顶部下移了一个NavigationBar导航高度的位置为源点。
从上面图可以看出整个NavigationController+层级结构:
1、self.navigationController.view其实是一个UILayoutContainerView。他的W-H是window的W-H,orgin是从设备显示屏左上角(0,0)开始的。
2、self.navigationController.view的subViews有两个
1)UINavigationTransitionView的frame还是同superView一样
-----subView是UIViewControllerWrapperView,origin(0,0)是从屏幕左上角开始。
-----subView是ViewController.view,orgin(0,0)是从屏幕下来NavBar+statusBar高度的位置开始。
----subView是tableView,orgin(0,0)是从屏幕下来NavBar+statusBar高度的位置开始。
(以iPhone8为例) 注意1:在ViewDidLoad里面的self.view.frame.size.height是屏幕的高度如图:
translucent与automaticallyAdjustsScrollViewInsets在NavigationContorller+ScrowView的显示问题总结
文章图片
注意2:在viewWillLayoutSubviews里面的self.view.frame.size.height是屏幕的高度如图:
translucent与automaticallyAdjustsScrollViewInsets在NavigationContorller+ScrowView的显示问题总结
文章图片
因此,由于navigationBar的translucent为NO,self.view及subViews会从新自适应调整其高度。也就是self.view的height=屏幕height-(navigationBar+statusBar)高度,所以我们最后看到的self.View的显示高度是减掉64(navigationBar+statusBar)后的高度(也是self.View在屏幕上的可显示区域)。但是由于tableView.frame=CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height),会导致tableView的高度超出可显示区域,这就会出现一个问题:tableView的内容有部分显示不全,在可显示区域下面有高度为(navigationBar+statusBar)高度64的不可见的内容区域,需要解决此问题两种思路:1、tableView的height减掉64(navigationBar高度)。2、self.tabView.contentInset = UIEdgeInsetsMake(0, 0, 64, 0); 显示内容区域底部缩进64
2)UINavigationBar坐标是(0,0,W,barHeight)从屏幕左上角顶点开始(self.navigationController.view的subView);
2、如果translucent=YES(默认状态)。也就是半透明效果,此时的self.View的orgrin(0,0)及tableView.origin的(0,0)都是从屏幕顶部开始的。此时tableView的内容cell完全可以显示正常,是因为内部做了自适应(ViewController.automaticallyAdjustsScrollViewInsets=YES),tableView的contentEdge区域是以屏幕高度减掉(navigationBar+statusBar)高度后的部分。此时contentInset={0,0,0,0}。tableView内容显示正常。如图红框区域是Edge区域:


translucent与automaticallyAdjustsScrollViewInsets在NavigationContorller+ScrowView的显示问题总结
文章图片
3、ViewController.automaticallyAdjustsScrollViewInsets是(ios7-11.0)
【translucent与automaticallyAdjustsScrollViewInsets在NavigationContorller+ScrowView的显示问题总结】scrollView.contentInsetAdjustmentBehavior (ios11,*)之后的属性。
此属性的作用是做适配内容布局的。automaticallyAdjustsScrollViewInsets默认YES,contentInsetAdjustmentBehavior 默认UIScrollViewContentInsetAdjustmentAutomatic,标识内容显示根据superView及上下文环境做自动适配处理。
上面的例子把translucent=YES。tableView.frame=CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height),tableView内容显示正常。是因为默认状态automaticallyAdjustsScrollViewInsets是YES,也就是会做自动适配。自动适配:是把navigationBar的高度留出,然后tableView的内容会从上述红色区域显示。content显示区域自动适配了。如果此时automaticallyAdjustsScrollViewInsets改成NO,tableView内容不再做自动适配,或者UIScrollViewContentInsetAdjustmentAutomatic,那么内容显示会对齐到屏幕顶部。效果如图:
translucent与automaticallyAdjustsScrollViewInsets在NavigationContorller+ScrowView的显示问题总结
文章图片
如果navigationBar.translucent=NO不透明,那么automaticallyAdjustsScrollViewInsets属性不管是YES or NO,都不会对目前的tableView的内容显示适配有任何影响。此时内容底部有部分显示不全,可以利用tableView的self.view.height-(navigationBar+statusBar)高度,或者self.tabView.contentInset = UIEdgeInsetsMake(0, 0, 64, 0); 解决显示问题。
总结:如果navigationBar+tableView的显示,需要navigationBar为半透明默认效果的话。tableView.frame可以直接(0,0,self.view.frame.size.width,self.view.frame.size.height).显示的cell内容会自适应到屏幕(automaticallyAdjustsScrollViewInsets默认YES)。如上图的红框区域。

    推荐阅读