1. UINavigationController提供的功能
- 导航控制器提供在不同页面之间的导航功能, 包括:
- push
- back.
- 统一的导航栏.
- 导航的手势(侧滑后退)
-
统一的工具栏
- 导航控制器维护一个堆栈结构. 一层一层.
- 入栈操作对应push, 但是不会销毁之底部的控制器
- 出栈操作对应back, 会销毁顶部的控制器(减少一个引用, 如果你想保留也可以)
-
back操作会很快, 因为不需要创建和加载视图.
2. UINavigationController适用的场景
- 导航控制器适用于信息架构的的组织结构是树形的情况.
- 典型的应用是列表和详细信息结构.
- 需要在顶部显示标题时, 也可以考虑适用导航控制器.
3. 通用的问题以及处理方案
- 导航控制器的样式
导航控制器的样式, 主要为导航条的样式, 需要保证导航条和UI设计的一致. 比如要不透明的导航条, 导航条字体的颜色需要是红色, 只显示返回的”<“图标而不显示上一个页面的title等等.
另外还包括工具条的样式。
处理方案包括:- 使用继承
可以创建一个父类, 将公用的导航控制器样式设置代码放-(void)viewDidLoad方法里面, 所有的使用同一个导航控制器样式的类, 都继承该类. - 使用组合
创建一个类,提供方法,输入参数是导航控制器,对导航控制器的样式进行设置。 - 使用分类category
创建一个UIViewController的分类,在分类中增加一个方法,用来设置导航控制器的样式。
** 架构选择
上面列出的方案,使用继承最节省代码,但是后两个的解耦更好,推荐使用后两个方案。
- 使用继承
- push时页面间数据的传输
导航控制器的push有两种方式,一种是利用storyboard的segue,另一种是使用导航控制器的push方法。两者对于传输数据来说,只是传输的时机不同。- 属性传值
在viewcontroller里增加属性,用来保存控制器间传输的值。 - 模型传值
在数据模型中存好值。由于控制器和模型所在层次不同,所以每个控制器都可以从模型中直接取值。 - 字典传值
将数据存入一个字典, 传输给下一个页面。该方法更为灵活,但是丢失了数据的类型。
** 架构选择
我使用的最多的是属性传值,更为简单易懂。问题是不够灵活,有时候需要根据实际状况调整。
- 属性传值
- back时页面间数据的传输及页面刷新
- 在viewVillAppear中刷新页面
back有两种方式,一种是调用导航控制器的pop方法,一种是利用侧滑手势。viewVillAppear能够同时处理这两种,所以在其中刷新一些数据的显示比较合适。 - 使用block属性
其他控制器给入栈的控制器利用block属性传入一个block,当某些数据的变化需要通知时,可以利用block传送数据。 - 直接操作模型对象
直接修改对象模型的话,back时,其他页面可以直接从模型中读取可能发生变化的数据并刷新。 - 将上一个控制器作为参数传入
当数据发生变化时,可以直接调用控制器提供的刷新和数据传送方法。 - 定义一个委托进行数据传送
上一个控制器实现委托方法,再将自己传给下一个控制器。 - 架构选择
使用委托应该是再设计上最优的,将控制器作为参数传入是实现上最不需要动脑筋的。
- 在viewVillAppear中刷新页面