UINavigationController
一、UINavigationController介绍
1.1、简介
UINavigationController manages a stack of view controllers and a navigation bar.
It performs horizontal view transitions for pushed and popped views while keeping the navigation bar in sync.
Most clients will not need to subclass UINavigationController.
If a navigation controller is nested in a tabbar controller, it uses the title and toolbar attributes of the bottom view controller on the stack.
UINavigationController is rotatable if its top view controller is rotatable.
Navigation between controllers with non-uniform rotatability is currently not supported.
导航控制器,可以轻松完成多个控制器之间的切换,其结构包含导航条、栈顶控制器的view、导航控制器的view。导航控制器需要设置一个根控制器,一般是UIViewController.
imageUINavigationBar: 是一个View,NavigaitonBar就是导航栏,位于屏幕的上方,管理整个NavigationController的navigationItem,即类似navigationController一样提供了一个栈来管理item。
UINavigationItem: 是一个NSObject,一般使用在self.navigationItem, 包含了当前页面导航栏上需要显示的全部信息(
title,prompt,titleView,leftBarButtonItem,rightBarButtonItem,backBarButonItem )。其中UIBarButtonItem是一个UIBarItem,是一种专门放在UINavigationBar上的特殊button。
UIToolbar: 是tool条,包括image,文字title
1.2、基本使用
1、初始化
UINavigationController *nav = [[UINavigationController alloc] init];
2、设置
window.rootViewController = nav;
[window makeKeyAndVisible];
3、基本方法
1 //UINavigationController以栈的形式保存子控制器
2 @property(nonatomic,copy) NSArray *viewControllers;
3 @property(nonatomic,readonly) NSArray *childViewControllers;
4
5 //使用push方法能将某个控制器压入栈
6 - (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated;
7
8 //使用pop方法可以移除控制器
9 //将栈顶的控制器移除
10 - (UIViewController *)popViewControllerAnimated:(BOOL)animated;
11 //回到指定的子控制器
12 - (NSArray *)popToViewController:(UIViewController *)viewController animated:(BOOL)animated;
13 //回到根控制器(栈底控制器)
14 - (NSArray *)popToRootViewControllerAnimated:(BOOL)animated;
4、修改导航栏的基本内容
1 //导航栏的内容由栈顶控制器的navigationItem属性决定
2
3 //UINavigationItem有以下属性影响着导航栏的内容
4 //左上角的返回按钮
5 @property(nonatomic,retain) UIBarButtonItem *backBarButtonItem;
6 //中间的标题视图
7 @property(nonatomic,retain) UIView *titleView;
8 //中间的标题文字
9 @property(nonatomic,copy) NSString *title;
10 //左上角的视图
11 @property(nonatomic,retain) UIBarButtonItem *leftBarButtonItem;
12 //右上角的视图
13 @property(nonatomic,retain)UIBarButtonItem *rightBarButtonItem
1.3、实际开发过程中一些问题
1、UINavigationBar背景颜色
//背景色
self.navigationBar.barTintColor = [UIColor blueColor];
//title字体
//[self.navigationController.navigationBar setTitleTextAttributes:@{NSForegroundColorAttributeName:[UIColor lightGrayColor],NSFontAttributeName:[UIFont systemFontOfSize:17]}];
//修改UIBarButtonItem 图片 title颜色
self.navigationBar.tintColor = [UIColor greenColor];
//是否半透明 当为YES时 设置的导航栏背景颜色会和实际rgb值有误差
self.navigationBar.translucent = NO;
//如果想要半透明效果 颜色没有色差 可以通过设置背景图片的方法 背景图片会覆盖barTintColor
//- (void)setBackgroundImage:(nullable UIImage *)backgroundImage forBarMetrics:(UIBarMetrics)barMetrics
2、自定义导航栏的返回按钮
//修改图片文字颜色
self.navigationController.navigationBar.tintColor = [UIColor whiteColor];
//替换图片
[self.navigationController.navigationBar setBackIndicatorImage:[UIImage imageNamed:@"erwema"]];
[self.navigationController.navigationBar setBackIndicatorTransitionMaskImage:[UIImage imageNamed:@"erwema"]];
//设置文字
UIBarButtonItem * backBarItem = [[UIBarButtonItem alloc]initWithTitle:@"返回" style:UIBarButtonItemStylePlain target:nil action:nil];
self.navigationItem.backBarButtonItem = backBarItem;
1.4、易混淆的知识点
1、self.title、self.navigationItem.title self.tabBarItem.title之间的关系
1、如果当前控制器通过self.navigationItem.titleView指定了自定义的titleView,系统将会显示指定titleView,设置self.title、self.navigationItem.title不会改变导航栏标题
2、如果当前控制器没有指定titleView,系统则会根据当前的控制器的title或者当前navigationItem.title的内容创建一个UILabel并显示。
3、self.title会重写navigationItem和tabBarItem的title
2、self.navigationItem,self.navigationController.navigationItem的关系
navigation是UIViewController的一个属性,navigationController继承UIViewController,navigationItem直接有ViewController管理。
1.5、 UINavigationTransitionView 内容区
在iOS 7.0之前我们的导航栏是拟物化风格的,导航条是不透明的,内容区是在导航栏下紧挨着的(Y值从64开始)
但是从iOS 7.0以后 我们的导航栏变成了扁平化风格,导航栏是透明的了,也就是说ViewController默认使用全屏布局
为了更好的过渡,苹果从iOS 7.0以后新增了几个属性
1、edgesForExtendedLayout
edgesForExtendedLayout是一个类型为UIRectEdge的属性,可以指定边缘要延伸的方向。因为iOS7之后鼓励全屏布局,它的默认值是UIRectEdgeAll,四周边缘均延伸,就是说如果即使视图中上有navigationBar,下有tabBar,那么视图仍会延伸覆盖到四周的区域。
2、extendedLayoutIncludesOpaqueBars
扩展布局是否包括不透明的Bars,默认为NO
苹果这样做其实是很人性化的,如果bars不透明的情况下,再使扩展布局到bars的下方,这样感觉是毫无意义的,所以在bars不透明的情况下,默认不会延伸布局
3、 automaticallyAdjustsScrollViewInsets
那么,当我们不想让系统自动为我们下移时我们可以这样设置:
if (@available(iOS 11.0, *)) {
self.tableView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
} else {
self.automaticallyAdjustsScrollViewInsets = NO;
}
导航栏调整。自定义导航栏未完待续、、、、
END.....