• UINavigationController 层级关系及一些常用设置


    UINavigationController一直是iOS开发中最常用的控件之一,但是一般就是工程开始时对其做一些统一的处理。后期操作就比较少了。导致虽然其很常用但是我们的熟悉程度却不是很高。今天就来记录一下我们常用的这个控件.

    UINavigationController继承自UIViewController,是一个基于栈的容器型控制器。既然是容器,他就能装一些东西。比如UIView能添加一些子视图,UINavigationController装的就是视图控制器。

    一个UINavigationController包含了几个部分:

    1.Navigation Stack 导航栈,它以栈的形式来管理视图控制器。栈的一个视图控制器(栈底),称为根视图控制器,其他称为子视图控制器。栈中的控制器可以通过self.navigationController找到UINavigationController的实例。

    2.UINavigationBar导航条 栈中的视图控制器会在顶部加一个导航条,虽然NavigationBar显示在子视图控制器的界面上,但是它是由UINavigationController实例管理的,不过导航条的内容却是由子视图控制器来决定的(通过self.navigationItem设置)

    3.UIToolbar工具栏,UINavigationController在子视图的底部提供了工具栏,默认不显示,也很少用到。

    常用的属性

    // 栈顶VC
    @property(nullable, nonatomic,readonly,strong) UIViewController *topViewController;
    // 如果存在模态视图控制器则返回模态视图控制器,否则顶视图控制器。
    @property(nullable, nonatomic,readonly,strong) UIViewController *visibleViewController;
    // 导航控制器目前栈中所管理的VC 
    @property(nonatomic,copy) NSArray<__kindof UIViewController *> *viewControllers;
    // 导航栏是否隐藏
    @property(nonatomic,getter=isNavigationBarHidden) BOOL navigationBarHidden;
    // 导航栏
    @property(nonatomic,readonly) UINavigationBar *navigationBar;
    // 工具栏是否隐藏, 默认为YES
    @property(nonatomic,getter=isToolbarHidden) BOOL toolbarHidden
    // 工具栏
    @property(null_resettable,nonatomic,readonly) UIToolbar *toolbar

    手势相关的属性

    // 返回手势识别器
    @property(nullable, nonatomic, readonly) UIGestureRecognizer *interactivePopGestureRecognizer
    // 属性为YES时,当键盘出现时,导航控制器的navigationBar工具栏将被隐藏。当键盘关闭时,这些条将保持隐藏状态,但只要在内容区域轻击一下,就会显示它们。
    @property (nonatomic, readwrite, assign) BOOL hidesBarsWhenKeyboardAppears
    // 当用户滑动时,导航控制器的导航栏和工具栏将被隐藏(向上滑动)或显示(向下滑动)。工具栏只有在有项目时才参与。
    @property (nonatomic, readwrite, assign) BOOL hidesBarsOnSwipe 
    // 手势识别器,如果滑动条将隐藏或显示,它将触发该手势识别器。不要更改委托或试图通过覆盖此方法来替换此手势。
    @property (nonatomic, readonly, strong) UIPanGestureRecognizer *barHideOnSwipeGestureRecognizer NS_AVAILABLE_IOS(8_0)
    // 当UINavigationController的垂直大小类是紧凑的时,隐藏UINavigationBar和UIToolbar。
    @property (nonatomic, readwrite, assign) BOOL hidesBarsWhenVerticallyCompact
    // 当用户点击时,导航控制器的navigationBar & toolbar将被隐藏或显示,这取决于导航栏的隐藏状态。工具栏只有在有要显示的项目时才会显示。
    @property (nonatomic, readwrite, assign) BOOL hidesBarsOnTap
    // 手势识别器,用于识别由于内容的点击而隐藏或显示的bar。不要更改委托或试图通过覆盖此方法来替换此手势。
    @property (nonatomic, readonly, assign) UITapGestureRecognizer *barHideOnTapGestureRecognizer

    常用的方法

    // 推进一个VC (压栈操作)
    - (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated;
    
    // 弹出导航控制器所管理的当前VC,返回值为弹出的视图控制器
    - (nullable UIViewController *)popViewControllerAnimated:(BOOL)animated; 
    
    // 弹出视图控制器,直到指定的在顶部。返回弹出的控制器。
    - (nullable NSArray<__kindof UIViewController *> *)popToViewController:(UIViewController *)viewController animated:(BOOL)animated; 
    
    //  直到堆栈上只剩下一个视图控制器。返回弹出的控制器。
    - (nullable NSArray<__kindof UIViewController *> *)popToRootViewControllerAnimated:(BOOL)animated;
    
    // 设置导航控制器所管理的VC 数组,如果动画是YES,那么根据新的top视图控制器是否先前在堆栈中模拟push或pop。
    - (void)setViewControllers:(NSArray<UIViewController *> *)viewControllers animated:(BOOL)animated

    UINavigationControllerDelegate

    //即将展示视图控制器时调用
    - (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated;
    //已经展示视图控制器时调用
    - (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated;
    //屏幕旋转时 NavigationController 支持的方向
    - (UIInterfaceOrientationMask)navigationControllerSupportedInterfaceOrientations:(UINavigationController *)navigationController API_AVAILABLE(ios(7.0)) API_UNAVAILABLE(tvos);
    //自控制器支持的方向
    /** 子控制器支持的方向
     * UIInterfaceOrientation 枚举类型
     *  1. UIInterfaceOrientationUnknown 设备的朝向不能确定。
     *  2. UIInterfaceOrientationPortrait  该设备处于竖屏模式,设备保持直立,底部的Home键。
     *  3. UIInterfaceOrientationPortraitUpsideDown 该设备处于竖屏模式,但上下颠倒,设备保持直立,顶部的Home键。
     *  4. UIInterfaceOrientationLandscapeLeft 设备处于横向模式,设备保持直立,右侧Home键。
     *  5. UIInterfaceOrientationLandscapeRight 该设备处于横向模式,设备保持直立,左侧Home键。
     */
    - (UIInterfaceOrientation)navigationControllerPreferredInterfaceOrientationForPresentation:(UINavigationController *)navigationController API_AVAILABLE(ios(7.0)) API_UNAVAILABLE(tvos);
    //自定义转场动画
    - (nullable id <UIViewControllerInteractiveTransitioning>)navigationController:(UINavigationController *)navigationController
                              interactionControllerForAnimationController:(id <UIViewControllerAnimatedTransitioning>) animationController API_AVAILABLE(ios(7.0));
    //自定义转场动画
    - (nullable id <UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController
                                       animationControllerForOperation:(UINavigationControllerOperation)operation
                                                    fromViewController:(UIViewController *)fromVC
                                                      toViewController:(UIViewController *)toVC  API_AVAILABLE(ios(7.0));

    常用的设置

    想要改变Bar的背景颜色可以这样设置

    self.navigationController.navigationBar.barTintColor = [UIColor redColor];

    取消半透明效果

    self.navigationController.navigationBar.translucent = NO;

    改变NavigationBar的标题颜色 和 字体大小

    NSDictionary *dic = [NSDictionary dictionaryWithObject:[UIColor blackColor]   forKey:NSForegroundColorAttributeName];
    self.navigationController.navigationBar.titleTextAttributes = dic;

    隐藏NavigationBar

    - (void)viewWillAppear:(BOOL)animated {
        [super viewWillAppear:animated];
        [self.navigationController setNavigationBarHidden:YES animated:animated];
    }
    
    - (void)viewWillDisappear:(BOOL)animated {
        [super viewWillDisappear:animated];
        [self.navigationController setNavigationBarHidden:NO animated:animated];
    }

    想要改变NavigationBar的前景颜色 也就是所有UIBarButtonItem的字体颜色可以如下设置

    self.navigationController.navigationBar.tintColor = [UIColor redColor];

    单独设置

    self.navigationItem.leftBarButtonItem.tintColor = [UIColor grayColor];

    当tableView等滑动时是否隐藏NavigationBar

    self.navigationController.hidesBarsOnSwipe = YES;

    当视图接受点击时 是否隐藏NavigationBar

    self.navigationController.hidesBarsOnTap = YES;

    当键盘出现时是否隐藏NavigationBar

    self.navigationController.hidesBarsWhenKeyboardAppears = YES;

    当屏幕改变方向时是否隐藏NavigationBar

    self.navigationController.hidesBarsWhenVerticallyCompact = YES;

    当视图被push完之后 是否隐藏NavigationBar

    self.navigationController.hidesBottomBarWhenPushed = YES;

    UINavigationController的层级

    我们创建一个简单的带UINavigationController的工程 看一下他们的层级 工具 Xcode11 模拟器iphone11

    从层级我们能清楚的看到UINavigationBar(层级选中的状态)及下层的子控件是我们需要操作的单元,但是从官方给我们留出来的接口来看 我们很难拿到Bar的子控件。

    上面的是最原始的Bar 我们可以加上一个标题再看一下.

    我们可以看到登陆这个Label在Bar下的第一级子试图 而且在最上层 对原始状态的Bar下的视图除了遮挡没有产生任何影响

    可以看到我们设置UINavigationBar的背景颜色是不会有效果的,因为其前面还有几个视图挡着Bar。

  • 相关阅读:
    ASP Loading
    haproxy中两个常用的宏
    数字签名-摘要等
    haproxy内存管理-free_list原理
    haproxy-代码阅读-内存管理
    网卡中断不均衡处理
    TIME_WAIT 另一种解决方式 SO_LINGER
    HTTP报文格式
    TIME_WAIT过多及解决
    awk如何向shell传值
  • 原文地址:https://www.cnblogs.com/huanying2000/p/13633987.html
Copyright © 2020-2023  润新知