2018-07-11 UINavigationControlle

作者: 肠粉白粥_Hoben | 来源:发表于2018-07-11 17:44 被阅读4次

    在做View Controller的生命周期的时候,由于要用到UINavigationController,就干脆继续学习了一波这个知识点,参考了这篇文章

    一.定义

    UINavigationController(导航控制器)是一个容器控制器,其内部有多个UIViewController(视图控制器)的内容,我们可以通过UINavigationControllerview属性获取到其自身的视图,在该视图上面有一个位于界面顶部的UINavigationBar(导航栏)和位于界面底部的默认隐藏的UIToolbar(工具栏),以及一个位于界面中间部分的UIViewControllerview

    UINavigationController层级结构

    当用户在UINavigationController的层级结构中来回切换的时候,UINavigationBarUIToolbar的内容会随之发生变化,但是其本身并不会发生变化,唯一发生变化的就是位于界面中间部分的UIViewControllerview

    二.UIViewController堆栈的管理

    UINavigationController通过其管理的UIViewController堆栈来决定展示在UINavigationController中间部位的内容,该内容由位于UIViewController堆栈的栈顶位置的UIViewController决定。

    下图的View ControllersUIViewController堆栈navigationBar是位于顶部的UINavigationBartoolBar是位于底部的UIToolbar

    UIViewController堆栈

    根据栈的定义,如果我们要实现这个栈的内容,既可以用push和pop对UIViewController进行操作,也可以直接设置UIViewController堆栈的内容。

    1.push

    //push
    //方法一
    /*
     * 参数一: UIViewController, 该参数不可以使用UITabBarController的实例
     * 参数二: 是否执行动画
     */
    [navigationController pushViewController:[[UIViewController alloc] init] animated:YES];
    
    //方法二
    /*
     * 参数一: UIViewController, 该参数不可以使用UITabBarController的实例
     * 参数二: 要求展示UIViewController的对象
     */
    [navigationController showViewController:[[UIViewController alloc] init] sender:nil];
    

    2.pop

    //pop一个UIViewController
    /*
     * 参数一: 是否执行动画
     * 返回值: 从UIViewController堆栈中Pop出来的UIViewController
     */
    UIViewController *viewController = [navigationController popViewControllerAnimated:YES];
    
    //一直pop到根视图控制器
    /*
     * 参数一: 是否执行动画
     * 返回值: 从UIViewController堆栈中Pop出来的UIViewController数组
     */
    NSArray *viewControllers = [navigationController popToRootViewControllerAnimated:YES];
    
    //一直pop到指定的UIViewController
    /*
     * 参数一: 指定UIViewController, 该UIViewController必须位于当前UIViewController堆栈中
     * 参数二: 是否执行动画
     * 返回值: 从UIViewController堆栈中Pop出来的UIViewController数组
     */
    NSArray *viewControllers = [navigationController popToViewController:navigationController.viewControllers[0] animated:YES];
    

    3.获取

    // 获取位于UIViewController堆栈栈顶位置的UIViewController
    UIViewController *viewController = navigationController.topViewController;
    

    三.UINavigationBar的管理

    UINavigationController通过位于UIViewController堆栈栈顶位置的UIViewControllernavigationItem属性(该属性位于UIViewControllerUINavigationControllerItem类目中)来管理UINavigationBar展示的内容,同时UINavigationController也提供了navigationBar属性, 允许开发者通过该属性设置UINavigationBar的外观。

    值得注意的是,UINavigationControllerUINavigationBardelegate, 其负责响应该UINavigationBarDelegate的代理方法, 并据此更新位于界面中间部分的UIViewController的视图。

    1.设置UINavigationBar的外观

    我们可以通过该属性设置UINavigationBar的外观, 但是不要通过该属性设置其frame, bounds, alpha等属性, 更不要修改其层级结构。

    // 属性
    @property(nonatomic, readonly) UINavigationBar *navigationBar;
    // 示例
    navigationController.navigationBar.barStyle = UIBarStyleDefault;
    

    2.设置UINavigationBar的隐藏状态

    // 属性
    @property(nonatomic, getter=isNavigationBarHidden) BOOL navigationBarHidden;
    // 示例
    navigationController.navigationBarHidden = YES;
    

    3.设置UINavigationBar的隐藏状态(可选动画)

    // 方法
    /*
     * 参数一: 隐藏状态
     * 参数二: 是否执行动画
     */
    - (void)setNavigationBarHidden:(BOOL)hidden animated:(BOOL)animated;
    // 示例
    [navigationController setNavigationBarHidden:YES animated:YES];
    

    四.UIToolbar的管理

    UINavigationController通过位于UIViewController堆栈栈顶位置的UIViewControllertoolbarItems属性(该属性位于UIViewControllerUINavigationControllerContextualToolbarItems类目中)来管理UIToolbar展示的内容,同时UINavigationController也提供了toolbar属性, 允许开发者通过该属性设置UIToolbar的外观。

    1.设置UIToolbar的外观

    // 属性
    @property(nonatomic, readonly) UIToolbar *toolbar;
    // 示例
    navigationController.toolbar.barStyle = UIBarStyleDefault;
    

    2.设置UIToolbar的隐藏状态

    // 属性
    @property(nonatomic, getter=isToolbarHidden) BOOL toolbarHidden;
    // 示例
    navigationController.toolbarHidden = NO;
    

    3.设置UIToolbar的隐藏状态(可选动画)

    // 方法
    /*
     * 参数一: 隐藏状态
     * 参数二: 是否执行动画
     */
    - (void)setToolbarHidden:(BOOL)hidden animated:(BOOL)animated;
    // 示例
    [navigationController setToolbarHidden:NO animated:YES];
    

    五.手势识别器的管理

    1.获取手势识别器

    // 侧滑返回手势识别器
    @property(nonatomic, readonly) UIGestureRecognizer *interactivePopGestureRecognizer;
    // 用于轻拍隐藏UINavigationBar与UIToolbar的手势识别器
    @property(nonatomic, readonly, assign) UITapGestureRecognizer *barHideOnTapGestureRecognizer;
    // 用于轻扫隐藏UINavigationBar与UIToolbar的手势识别器
    @property(nonatomic, readonly, strong) UIPanGestureRecognizer *barHideOnSwipeGestureRecognizer;
    // 示例
    UIGestureRecognizer *interactivePopGestureRecognizer = navigationController.interactivePopGestureRecognizer;
    

    2.通过手势隐藏UINavigationBar与UIToolbar

    // 轻拍隐藏、再次轻拍显示
    @property(nonatomic, readwrite, assign) BOOL hidesBarsOnTap;
    // 向上轻扫隐藏、向下轻扫显示
    @property(nonatomic, readwrite, assign) BOOL hidesBarsOnSwipe;
    // 横屏隐藏(此时轻拍显示)、竖屏显示
    @property(nonatomic, readwrite, assign) BOOL hidesBarsWhenVerticallyCompact;
    // 键盘出现隐藏、键盘消失保持隐藏(此时轻拍显示)
    @property(nonatomic, readwrite, assign) BOOL hidesBarsWhenKeyboardAppears;
    // 示例
    navigationController.hidesBarsOnTap = YES;
    

    六.UINavigationController对象的初始化

    //通过UIViewController初始化
    /*
     * 参数一: UIViewController, 该参数不可以使用UITabBarController的实例
     */
    UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:[[UIViewController alloc] init]];
    
    //通过UINavigationBar、UIToolbar初始化
    /*
     * 参数一: 自定义UINavigationBar的子类, 如果是nil则为UINavigationBar类
     * 参数二: 自定义UIToolbar的子类, 如果是nil则为UIToolbar类
     */
    UINavigationController *navigationController = [[UINavigationController alloc] initWithNavigationBarClass:[UINavigationBar class] toolbarClass:[UIToolbar class]];
    

    七. UINavigationBar

    1.概述

    UINavigationBar是一个在层级结构中起导航作用的视觉控件, 其一般展示形式如下图所示

    2.UINavigationItem堆栈的管理

    UINavigationBar虽然继承自UIView, 但是其并非通过addSubview:方法来添加子视图, 而是通过其管理的UINavigationItem堆栈来决定展示在UINavigationBar中的内容。

    如下图所示,其中:
    itemsUINavigationItem堆栈;
    topItem是位于UINavigationItem堆栈栈顶位置的UINavigationItem;
    backItem是位于UINavigationItem堆栈栈顶下方位置的UINavigationItem

    我们可以利用系统提供的方法向UINavigationItem堆栈中Push一个UINavigationItem, 从UINavigationItem堆栈中Pop一个UINavigationItem, 也可以直接设置UINavigationItem堆栈中的全部UINavigationItem

    3. UINavigationBar的内容

    UINavigationBar通过UINavigationItem堆栈按照如下方式来决定展示在UINavigationBar中的内容

    位于中间的标题会根据下方顺序选择展示的内容:

    • 如果topItem设置了标题视图(titleView属性), 则展示标题视图

    • 如果topItem设置了标题文字(title属性), 则展示标题文字

    • 如果以上都未设置, 则展示空白

    位于右侧的按钮会根据下方顺序选择展示的内容:

    • 如果topItem设置了右侧按钮(rightBarButtonItem属性), 则展示右侧按钮

    • 如果以上都未设置, 则展示空白

    位于左侧的按钮会根据下方顺序选择展示的内容:

    • 如果topItem设置了左侧按钮(leftBarButtonItem属性), 则展示左侧按钮

    • 如果backItem设置了返回按钮(backBarButtonItem属性), 则展示返回按钮

    • 如果backItem设置了标题文字(title属性), 则展示利用标题文字封装的返回按钮

    • 如果以上都未设置, 则展示利用文字"Back"封装的返回按钮(前提是UINavigationItem堆栈中有超过一个的UINavigationItem

    // 初始化UINavigationItem对象
    /*
     * 参数一: 标题文字
     */
    - (instancetype)initWithTitle:(NSString *)title;
    // 示例
    UINavigationItem *navigationItem = [[UINavigationItem alloc] initWithTitle:@"Owen"];
    
    //设置标题文字
    // 属性
    @property(nonatomic, copy) NSString *title;
    // 示例
    navigationItem.title = @"Title";
    
    //设置标题视图
    // 属性
    @property(nonatomic, strong) UIView *titleView;
    // 示例
    navigationItem.titleView = [UIButton buttonWithType:UIButtonTypeInfoLight];
    
    //设置提示文字
    // 属性
    @property(nonatomic, copy) NSString *prompt;
    // 示例
    navigationItem.title = @"Prompt";
    
    //设置返回按钮
    // 属性
    @property(nonatomic, strong) UIBarButtonItem *backBarButtonItem;
    // 示例
    UIBarButtonItem *barButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Owen" style:UIBarButtonItemStylePlain target:nil action:nil];
    navigationItem.backBarButtonItem = barButtonItem;
    

    4.UINavigationBar的外观

    UINavigationBar类中提供了大量属性/方法用于设置其外观, 我们可以设置其样式、背景颜色、色彩颜色、文字属性等

    同样, 我们也可以设置其背景图片、阴影图片等

    //设置样式
    //该属性默认为UIBarStyleDefault(白底黑字), 可选项为UIBarStyleBlack(黑底白字)
    navigationBar.barStyle = UIBarStyleDefault;
    
    //设置透明性
    navigationBar.translucent = YES;
    
    //设置背景颜色
    navigationBar.barTintColor = [UIColor orangeColor];
    
    //设置色彩颜色
    navigationBar.tintColor = [UIColor greenColor];
    
    //设置标题文字属性
    navigationBar.titleTextAttributes = @{NSFontAttributeName: [UIFont systemFontOfSize:30], NSForegroundColorAttributeName: [UIColor whiteColor]};
    
    //设置/获取背景图片
    /*
     * 参数一: 背景图片
     * 参数二: 默认为UIBarPositionAny(不指定), 可选项为UIBarPositionBottom(在容器下方), UIBarPositionTop(在容器上方), UIBarPositionTopAttached(在屏幕上方, 与容器平级)
     * 参数三: 可选项为UIBarMetricsDefault(竖屏, 横屏未设置也使用该效果), UIBarMetricsCompact(横屏), UIBarMetricsDefaultPrompt(拥有提示文字的竖屏, 横屏未设置也使用该效果), UIBarMetricsCompactPrompt(拥有提示文字的横屏)
     */
    [navigationBar setBackgroundImage:[UIImage imageNamed:@""] forBarPosition:UIBarPositionTop barMetrics:UIBarMetricsDefault];
    
    //设置阴影图片
    navigationBar.shadowImage = [UIImage imageNamed:@""];
    
    //设置返回按钮图片(需要同时设置)
    navigationBar.backIndicatorImage = [UIImage imageNamed:@""];
    navigationBar.backIndicatorTransitionMaskImage = [UIImage imageNamed:@""];
    

    相关文章

      网友评论

        本文标题:2018-07-11 UINavigationControlle

        本文链接:https://www.haomeiwen.com/subject/xqmhpftx.html