简介
导航控制器UINavigationController可以凭借少量代码,实现在不同界面之间的往返。它提供完整的历史记录控制,自动处理返回和内存,并且无需任何复杂的编码。
UINavigationController导航控制器是UIViewController的子类,它维护着一个导航栈型结构。
导航控制器可以作为一个容器来管理其内部的控制器,控制器可以被推入导航栈,也可以被推出。
导航控制器默认显示的是栈顶的控制器。
初始化
- (instancetype)initWithRootViewController:(UIViewController *)rootViewController;
常用属性
topViewController:栈顶控制器
visibleViewController:当前显示控制器
viewControllers:栈内所有控制器
navigationBar:导航栏
navigationBarHidden:导航栏隐藏状态
toolbar:工具栏
toolbarHidden:工具栏隐藏状态
rootViewController:根视图控制器
界面跳转
每个导航控制器都有一个根视图控制器,从根视图控制器推送到新的视图控制器就会自动构建一个返回按钮。新的视图控制器依然可以继续推送,并且导航控制器会自动记录每个推送,确保每次都能准确地返回上一个控制器。推送到一个视图控制器,会进行界面的控制权移交,但是上一个控制器存在于栈中,不会被释放。
返回上一个控制器会将视图弹出栈,系统会自动释放这部分内存而不需要手动管理(注意,自动释放的前提是编码的时候没有对视图控制器做其他导致retainCount+1的操作,比如添加了NSTimer重复任务)。
推入push
// 推送方法
- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated;
推出pop
// 推出方法
// 1、返回到上一个视图控制器
- (nullable UIViewController *)popViewControllerAnimated:(BOOL)animated;
// 2、返回到指定视图控制器
- (nullable NSArray<__kindof UIViewController *> *)popToViewController:(UIViewController *)viewController animated:(BOOL)animated;
// 3、返回到根视图控制器
- (nullable NSArray<__kindof UIViewController *> *)popToRootViewControllerAnimated:(BOOL)animated;
Tips:
一个控制器只能返回它的推送历史中存在的控制器,如果不在这个推送的历史记录中,即使他们拥有同一个根视图控制器,也无法返回。
导航控制器与视图控制器的推送关系可以用下图描述:
导航栏 UINavigationBar
导航栏高度64 = 导航栏(44) + 状态栏(20);
导航栏的translucent
属性会直接影响屏幕坐标系原点。如果导航栏透明(值为YES),控制器视图坐标系原点默认位置在屏幕左上角,即{0,0}点位置;导航栏不透明(值为NO),控制器视图坐标系原点相对屏幕左上角在Y轴向下偏移64个像素,即{0, 64}点位置。
常用属性
barTintColor:背景颜色
tintColor:模板色
translucent:是否半透明
titleTextAttributes:标题属性
// 系统键:
// 1、NSFontAttributeName:字体
// 2、NSShadowAttributeName:阴影
// 3、NSForegroundColorAttributeName:字体颜色
navigationController = @{NSFontAttributeName : [UIFont boldSystemFontOfSize:20],NSForegroundColorAttributeName : [UIColor whiteColor]};
- self.navigationItem.titleView:标题视图
Tips
导航栏以及状态栏全部透明的方法,请点击这里,全透明方法是基于Swift实现,对于没有Swift编程基础的开发者可参考转换成OC。
工具栏 UIToolbar
工具栏默认隐藏,要显示工具栏,需将toolbarHidden属性置为YES;
常用属性
barTintColor:背景颜色
tintColor:模板色
translucent:是否半透明
UIBarButtonItem
导航栏、工具栏按钮元素。
初始化
// 1、图片初始化item
- (instancetype)initWithImage:(UIImage *)image style:(UIBarButtonItemStyle)style target:(id)target action:(SEL)action;
// 2、标题初始化item
- (instancetype)initWithTitle:(NSString *)title style:(UIBarButtonItemStyle)style target:(id)target action:(SEL)action;
// 3、系统初始化item
- (instancetype)initWithBarButtonSystemItem:(UIBarButtonSystemItem)systemItem target:(id)target action:(SEL)action;
// 4、自定义初始化item
- (instancetype)initWithCustomView:(UIView *)customView;
添加item
导航栏:
// 导航栏左边
self.navigationItem.leftBarButtonItem = item
self.navigationItem.leftBarButtonItems = @[item1, item2, item3...]
// 导航栏右边
self.navigationItem.rightBarButtonItem = item
self.navigationItem.rightBarButtonItems = @[item1, item2, item3...]
工具栏:
self.toolbarItems = @[item1, item2, item3...]
自定义返回按钮
UIBarButtonItem *item = [[UIBarButtonItem alloc] initWithTitle:@"自定义返回按钮"
style:UIBarButtonItemStylePlain
target:nil
action:nil];
self.navigationItem.backBarButtonItem = item
// 如果想要隐藏某一个视图控制器中的返回按钮,则到当前控制器执行如下方法:
self.navigationItem.hidesBackButton = YES;
Tips
当前控制器的返回按扭需要到上一个视图控制器自定义,比如从Nav1 push -> Nav2,Nav2的返回按钮需要到Nav1中去自定义;
常用方法
1、入栈隐藏工具栏
self.hidesBottomBarWhenPushed = YES;
2、设置导航栏、工具栏背景图片
- (void)setBackgroundImage:(UIImage *)backgroundImage forBarPosition:(UIBarPosition)barPosition barMetrics:(UIBarMetrics)barMetrics