美文网首页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