刚接触导航控制器的人往往会感到一些困惑,例如标题配置、颜色修改、左右返回按钮之类的配置,写这篇文不仅仅是提供解决问题的方法,也加入了导航对于控制器和显示的管理,希望可以加深理解,更有利于记忆。
1、综述: UINavigationController负责管理三种不同的内容展示,一个是UIViewController,用来展示当前内容,一个是UINavigationBar,使用UINavigationItem展示导航栏,一个是UIToolbar。
他们的关系是:
一个UINavigationController管理多个UIViewController。
一个UINavigationController只管理一个UINavigationBar,而UINavigationBar会管理多个UINavigationItem(这是真正负责展示导航栏显示的控件),每个UINavigationItem会和UIViewController一一对应,通过UIViewController的navigationItem可以直接拿到。
UINavigationController管理多个UIToolbar,每个UIToolbar都与UIViewController一一对应。通过UIViewController的setToolbarItems可以进行设置。把toolbarHidden属性设为NO开启UIToolBar。
如果你对于以上所说关系非常明了,很好,证明你对于UINavigationController已经比较了解,也很容易理解后面内容,如果不是很明白也没关系,后续还会有一些说明,可以返回对比继续看。
2、如何修改导航的标题文字?
太简单了,在展示内容的UIViewController来调用 self.navigationItem.title = @“TITLE”
等等,不管用?很可能你使用了tabBarController,这样UINavigationItem对应的就是tabBarController而不是展示内容的UIViewController。
因此,如果在UINavigationController中使用了tabBarController,则UINavigationController管理的是tabBarController,因此如果在tabBarController的内容页,则需要使用self.tabBarController.navigationItem来获取。
因为切换tab需要修改标题?把修改放在这里就好
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
self.navigationItem.title = @“change here";
}
3、如何修改回退按钮?
UINavigationController使用数组来管理UIViewController,可以通过viewControllers属性来访问,使用方式则是堆栈的模式,后进先出,当我们没有任何配置的时候,被压入的新界面也会有一个回退按钮回到之前的页面,一般会显示为
场景1:我只想配置当前页面的返回按钮。这也是最直接的想法,也是优先级最高的方法,生成一个UIBarButtonItem,并在当前页面设置navigationItem.leftBarButtonItem(不是barBar),则回退按钮就是你想要的按钮。
场景2:我的主页面有很多地方需要进入下一级页面,如果每个都配置,过于繁琐。这个时候,可以在主页面,也就是上一级页面,配置navigationItem.backBarButtonItem,这样每个下级页面返回时,都会使用这个按钮。
4、修改导航栏的颜色,各种颜色!
之前两个问题,我们是跟navigationItem打交道,因为不同的页面需要不同的配置。但是要记住UINavigationBar是管理navigationItem的,而颜色统一还是会比较好,所以现在,我们要使用UINavigationBar来配置,一劳永逸。
navigationBar.barTintColor更改导航条背景色
navigationBar.tintColor更改按钮颜色,但是不包括导航栏Title, 在设定barTintColor的时候,由于导航条默认是半透明的(>=IOS7),因此显示出的颜色跟设定颜色会有偏差,因此需要设定navigationBar.translucent = NO,这样就是设定的颜色了。工具栏同理
navigationBar.barStyle更改样式,涉及Title颜色
navigationBar.titleTextAttributes更改title的显示
titleTextAttributes属于全方位的修改,颜色字体显示格式等等,这里不详述了,一点小技巧,如果只需要修改title颜色为白色,则只需要设置 navigationBar.barStyle = UIBarStyleBlack即可。
如果你觉得配置背景颜色不满意,可以用图来解决问题
[self.navigationBar setBackgroundImage:[UIImage imageNamed:@"image"] forBarMetrics:UIBarMetricsDefault];
5、相关问题:状态栏的颜色配合
因为navigationBar的颜色变化也会影响到状态栏,也就是时间电量等等的显示,默认为黑色,如果想要修改为白色,使用以下两步:
第一步:打开**-Info.plist
点击根节点的+号新增一行:View controller-based status bar appearance,并设置为NO
第二步: General选项卡Status bar style 修改为Light
6、如何让导航栏丰富起来
当然,你可以把导航栏navigationBar看做一个View来操作,随意去配置,不过这就不在我们的讨论范围了。不过要记住是navigationBar,而不是navigationItem,因为它不是继承自UIView类的。
使用UIBarButtonItem来生成各种需要的按钮。
可以使用标题文字,图片,或者系统按钮,这里不详述了。
使用customView来自定义,不受navigationBar各种配置的影响
把按钮加入navigationItem来使用:
UIBarButtonItem *item = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemRewind target:self action:@selector(back)];
self.navigationItem.leftBarButtonItem = item
多个则使用数组 self.navigationItem.leftBarButtonItems = @[item1, item2]
使用rightBarButtonItem,rightBarButtonItems加入右侧
navigationItem可以使用titleView,同样不受navigationBar各种配置的影响
7、做按钮的时候,我想要图原始颜色,但是它被你说的tintColor影响了,怎么办?
UIBarButtonItem *right = [[UIBarButtonItem alloc]init];
right.image = [UIImage imageNamed:@“image"]; //使用tintColor
改为
right.image = [[UIImage imageNamed:@“image"]imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]; //使用原始颜色
8、一些补充
UINavigationController使用push(pop)ViewController压入和弹出新页面。
navigationItem使用属性prompt,可以在标题之上添加文字,会使得导航栏高度增加
9、导航栏导致ScrollView的位移问题
突然想到这个刚学IOS曾经困扰我的问题,当使用导航栏,并且内容视图的第一个子view是ScrollView的时候,如果使用自动布局,或者手动设置ScrollView的frame留出了导航栏的位置,ScrollView里的内容也会空出导航栏的高度。原因是
:
Navigation bars automatically add a scroll content inset to your scroll view (assuming it is the root view of your view controller)
也就是说导航栏自动给满足条件的ScrollView设置了contentInset。
避免这个问题的方法,一个就是直接把frame设为(0,0,height,width),不要保留高度
另一个则是设置UIViewController的automaticallyAdjustsScrollViewInsets为NO