nav图文讲解(总结)

  1. 首先是导航控制器下的视图结构
图片.png
  • 导航控制器的三个区:
    导航区:导航控制器的navigationBar,管NSArray *items;数组
    内容区:用于展示导航控制器字控制器的视图
    toolbar区:底部工具条,默认隐藏

  • 导航条的隐藏和展示:
    通过navigationBar.translucent = YES/NO调节。
    透明情况下:
    内容区从屏幕顶部开始, 控制器view的frame为 0 0 screenW screenH(控制器的View的frame相对于UIViewControllerWrapperView计算)
    透明情况下,让控制器的展示区从导航条底部开始:self.edgesForExtendedLayout = UIRectEdgeNone;设置后,展示区的高度同样-64px。同时automaticallyAdjustsScrollViewInsets失效,scrollView的bounds不自动下移。
    测试:UIViewControllerWrapperView = self.view.superView。更改bounds也可以让self.view下移64,
    导航条不透明情况下:
    展示区从导航条下开始 。
    导航条不透明情况让展示区顶部从屏幕顶部开始:self.extendedLayoutIncludesOpaqueBars = YES; 同时automaticallyAdjustsScrollViewInsets生效。同时automaticallyAdjustsScrollViewInsets自动生效,scrollView的bounds自动下移。

    无论导航条是否透明,UILayoutContainerView、UINavigationTransitionView、UIViewControllerWrapperView都是和屏幕尺寸一致的,变化的只是展示区域的frame,即子控制器的view的frame。
    测试:导航控制器下view加载:只要在控制器view不是从顶部0开始的情况下,控制器的view的y和height都是不准确的,当子控制器的viewDidAppear的时候,它的frame是会被重新定义成展示区的尺寸。我把展示区理解成子控制器viewDidAppear后的frame。

  • 导航条透明度的调节:
    方法一:通过setBackgroundImage调节。
    viewDidLoad、viewWillAppear设置setBackgroundImage为一张透明度为1.0的图片话,相当于设置navigationBar.translucent = NO,展示区下移64px,高度减少64px。
    viewDidAppear设置setBackgroundImage为一张透明度为1.0的图片话,相当于设置navigationBar.translucent = NO。但是当前控制器不会显现,展示区还是0px,高度还是屏幕的尺寸,内部的scrollView的bounds还是会自动加64px。pop回上一层控制器后,展示区下移64px,高度减少64px。如果设置setBackgroundImage为一张透明度小于1.0的图片话,就不会出现navigationBar.translucent状态不会修改。

解决的设置非透明图片后,顶栏透明自动关闭的问题:
viewDidLoad设置
[self.navigationController.navigationBar setBackgroundImage:[UIImage imageWithColor:JKRColor(255, 255, 0, 1.0)] forBarMetrics:UIBarMetricsDefault];
self.extendedLayoutIncludesOpaqueBars = YES;

viewWillDisappear设置
self.navigationController.navigationBar.translucent = YES;

解决设置完setBackgroundImage为一张非透明图片之后,展示区顶部回到0位置:再设置self.navigationController.navigationBar.translucent = YES;会回恢复展示区y为0的位置,但是设置的图片会自动加一些透明度。


nav图文讲解(总结)_第1张图片
1.png

会出现的问题:如果设置setBackgroundImage同时设置barTinkColor,那么图片透明会漏出_UIBarBackground的颜色。
如果设置上一级的控制器设置了setBackgroundImage,下一级的控制器设置setBackgroundImage图片为透明色后,底部_UIBarBackground的变为不透明,漏出黑色,不能穿透显示底部视图。


nav图文讲解(总结)_第2张图片
2.png

方法二:通过修改_UIBarBackground的背景色
nav图文讲解(总结)_第3张图片
图片.png

首先viewDidLoad中定义当前控制器的导航条为非透明状态,展示区不自动下移。
设置导航条背景色被透明。
遍历导航条获取到_UIBarBackground
根据透明度设置其颜色
pop时,即viewWillDisappear时重新定义导航条为透明

遇到的问题:当侧滑并返回不POP的时候,当前控制器的导航条的_UIBarBackground背景色虽然透明,但是导航条还是白色,观察发现,因为POP一半的时候走了viewWillDisappear并执行self.navigationController.navigationBar.translucent = YES;返回的时候,导致导航条内部增加了UIVisualEffectView。我尝试在viewDidAppear中遍历出这个视图移除,但是没有效果。发现控制器的view加载成功后,再次对导航条修改必须要等viewDidAppear后一段时间才可以,没有找出来原因。代码如下:


nav图文讲解(总结)_第4张图片
815022546DBD4216142B3EF205E5F066.png
nav图文讲解(总结)_第5张图片
907B3330DDA5682F7CB97A1C7F077402.gif

5.导航条下划线的隐藏:
方法一:设置navigationBar的clipsToBounds。问题:navigationBar为44高度,有背景色的时候会发现问题。
方法二:遍历出下划线的UIImageView并隐藏。原理:因为下划线的高度为0.333,以高度不大于0.4为条件便利导航条的子视图。

6.Item间距问题。
UIBarButtonItem *itemGap = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil];
itemGap.width = 80;
把间距的item添加到items对象数组中要添加间距的两个对象之间即可

你可能感兴趣的:(nav图文讲解(总结))