美文网首页iOS Developer
iOS开发-UINavigationController

iOS开发-UINavigationController

作者: Huangbaoqin | 来源:发表于2017-04-13 23:48 被阅读285次
    NavDemo.gif

    说明:在Demo中Windows的根控制器为UINavigationController,修改其View背景色为深蓝色,其根控制器为背景色为浅蓝色的FirstViewController,NEXT按钮push进下一个UIViewController。
    UINavigationController的ToolBar默认隐藏,在FirstViewController中设置不隐藏。

    UINavigationController结构解析

    • UINavigationController view结构
    nav_平面图.png nav_调试图.png nav_层次结果解析.png
    • UINavigationController栈结构
    Nav栈结构.jpg

    UINavigationController通过push/pop方法进行转场,这就意味着UINavigationController管理的view controller 是栈结构的(LIFO--先进后出)。如图所示viewControllers数组就是当前被推进栈的view controller组成的数组

    // UINavigationController的两个属性
    @property(nonatomic,copy) NSArray<__kindof UIViewController *> *viewControllers; // 当前在栈中view controller
    @property(nullable, nonatomic,readonly,strong) UIViewController *topViewController; // 在栈顶的view controller
    

    UINavigationController问题

    下面通过几个问题来补充说明UIViewController的其他内容

    1.topViewController的视图是如何布局的?

    UIRectEdgeAll.png

    从上图我们可以观察到FirstViewController及UINavigationController的topViewController的大小和UINavigation的view(深蓝色部分)是一样,有时候我们又希望topViewController不要被NavigationBar和ToolBar覆盖,这个时候我们应该怎么设置呢?

    @property(nonatomic,assign) UIRectEdge edgesForExtendedLayout NS_AVAILABLE_IOS(7_0); // Defaults to UIRectEdgeAll
    @property(nonatomic,assign) BOOL extendedLayoutIncludesOpaqueBars NS_AVAILABLE_IOS(7_0); // Defaults to NO, but bars are translucent by default on 7_0.
    

    UIViewController有如上两个属性,其中edgesForExtendedLayout为UIRectEdge类型

    typedef NS_OPTIONS(NSUInteger, UIRectEdge) {
        UIRectEdgeNone   = 0,
        UIRectEdgeTop    = 1 << 0,
        UIRectEdgeLeft   = 1 << 1,
        UIRectEdgeBottom = 1 << 2,
        UIRectEdgeRight  = 1 << 3,
        UIRectEdgeAll    = UIRectEdgeTop | UIRectEdgeLeft | UIRectEdgeBottom | UIRectEdgeRight
    } NS_ENUM_AVAILABLE_IOS(7_0);
    

    当extendedLayoutIncludesOpaqueBars为默认的NO且navigationBar和ToolBar均为半透明效果时设置edgesForExtendedLayout效果如下所示

    UIRectEdgeAll.png UIRectEdgeNone.png UIRectEdgeTop.png UIRectEdgeBottom.png

    这时候如果设置NavigationController的NavigationBar和ToolBar为不透明效果

    [self.navigationController.navigationBar setTranslucent:NO];
    [self.navigationController.toolbar setTranslucent:NO];
    

    在extendedLayoutIncludesOpaqueBars为默认的NO情况下设置edgesForExtendedLayout为UIRectEdgeAll,效果如图所示

    self.edgesForExtendedLayout = UIRectEdgeAll;
    [self.navigationController.navigationBar setTranslucent:NO];
    [self.navigationController.toolbar setTranslucent:NO];
    [self setExtendedLayoutIncludesOpaqueBars:NO];
    
    Bar不半透明_UIRectEdgeAll_setExtendedLayoutIncludesOpaqueBars = NO.png

    这个时候如果想将FirstViewController布局到bar上面去,只需要设置ExtendedLayoutIncludesOpaqueBars(延伸到不透明区域)为YES即可

    self.edgesForExtendedLayout = UIRectEdgeAll; 
    [self.navigationController.navigationBar setTranslucent:NO];
    [self.navigationController.toolbar setTranslucent:NO];
    [self setExtendedLayoutIncludesOpaqueBars:YES];
    
    ExtendedLayoutIncludesOpaqueBars == YES.png

    总结:edgesForExtendedLayout控制topViewController在UINavigationController上的布局,extendedLayoutIncludesOpaqueBars为YES时可延伸到不透明区域([bar setTranslucent:NO]来设置为不透明)

    // 所以通过以下几个属性就可以设置topViewController在UINavigationController上的布局了
    self.edgesForExtendedLayout = UIRectEdgeAll; 
    [self.navigationController.navigationBar setTranslucent:NO];
    [self.navigationController.toolbar setTranslucent:NO];
    [self setExtendedLayoutIncludesOpaqueBars:YES];
    

    2.UINavigationController有多个view controller却只有一个navigationBar,怎么针对不同的view controller展示不同的顶栏

    Nav栈结构.jpg

    说明:UINavigationController由viewControllers、navigationBar、toolBar组成,其中navigationBar中有一个items属性的数组存放UINavigationItem数据,与UINavigationController中的viewControllers一一对应。也是栈结构的。在UINavigationItem中有title、titleView等属性,不同的viewController持有不同的UINavigationItem,通过设置UINavigationItem的属性可实现一个navigationBar为不同的viewController展示不同的顶栏的效果啦。

    未完待续...

    相关文章

      网友评论

        本文标题:iOS开发-UINavigationController

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