原生导航栏太难用?可能是你还没彻底明白MVC

96
溪石iOS Excellent
5.6 2019.02.03 16:44 字数 506

经常有开发者抱怨原生的导航栏不好用,不是总是改变不了其样式,就是有意外的动画效果,其实大多时候,是开发者混淆了导航栏和导航控制器这两个概念。
苹果原生框架几乎都严格遵循MVC,导航栏的设计也体现了典型的小MVC设计思想,下面通过对原生导航栏的分析,深入理解学习MVC设计模式。

角色分工:

UINavigationController的MVC分工
  • View: UINavigationBar
  • Controller: UINavigationController
  • Model: UINavigationItem 栈

控制器:UINavigationController

UINavigationController 作为核心的控制器,持有 UINavigationBar 和 UIViewController 组,接收 UINavigationBar 发来的 pop或push请求,控制UIViewController 组实际出入栈,并将当前显示的UIViewController的UINavigationItem返回给 UINavigationBar。
UINavigationController是容器类控制器之一,应该作为管理其他控制器的主控制器,在APP架构中需严格控制其数量。

模型:UINavigationItem 栈

UINavigationItem 保存的是导航栏的内容,与视图的对应关系如下图:


UINavigationItem对应的值

每个UIViewController 都有自己的 UINavigationItem,UINavigationController 将它管理的UIViewController 放入一个栈结构中,即 viewControllers(NSArray),自然对应的 UINavigationItem 组成了一个栈结构,模型层就是由这些 UIViewController及其关联的UINavigationItem 组成,体现了模型组的概念。
当你需要改变导航栏的内容(如返回按钮标题)时,直接设置当前VC的navigationItem属性,而不应该直接通过setItems设置UINavigationBar,因为这有可能引发默认的弹出动画。

视图:UINavigationBar

UINavigationBar 通过 UINavigationBarDelegate 通知 UINavigationController ,由于动画效果,看起来每次进入新页面都会新建,实际上 UINavigationBar 只有一个,所以任意 UIViewController 都有可能永远改变UINavigationBar的外观,因此在处理外观时,需要遵循“谁改变,谁复原”的原则,防止导航栏混乱。

iOS开发基础系列
Gupao