View Controller 基本知识(三)
3.视图控制器协同工作创建app界面
视图控制器管理着它们的视图及其相关的对象,但是它们也配和其他的视图控制器提供平滑的用户界面。app中视图控制器之间的工作分配和通讯是至关重要的部分。因为这些关联关系对于创建复杂的app是非常重要的,下面这部分中我们详细讨论这些内容。
父子关系
一个视图控制器层级始于一个父类,即窗口的根视图控制器。如果这个视图控制器是一个容器,那容器可能拥有提供内容的子视图控制器。这些控制器,按顺序,可能也会是拥有自己子视图控制器的容器类型。图1-11就是一个视图控制器层级的例子。根视图控制器是一个有四个选项卡的选项栏视图控制器,第一个选项卡使用了有子控制器的导航视图控制器,其余三个选项卡被没有子控制器的内容视图控制器管理。
图1-11视图控制器的界面可填充区域受父控制器决定,根视图控制器的填充区域决定于window。图1-11中,选项栏视图控制器从window获取它的尺寸,其又准备空间给它的选项卡栏,然后将剩余空间给子视图控制控。如果导航控制器正在控制显示,它要给其导航栏准备空间,然后分配剩余的空间给它的内容控制器。每一步操作中,子视图控制器的视图都会被父控制器缩放,并且被放置近父控制器的视图层级。
这种组合视图和视图控制器也建立了应用程序事件处理响应链。
同级关系
定义被子控制器共享关联关系的这类容器控制器,例如,我们比较下选项栏视图控制器和导航控制器。
1)选项栏视图容器中,选项栏代表内容区域,选项工具栏并没有在子控制器中定义关联关系,尽管我们的app可以选择这样做;
2)导航控制器中,同级视图显示了在被安排在一个堆栈中相关的视图元素,同级视图通常共享一个链接与毗邻的同级视图。
图1-12显示了一个视图控制器和相关的导航控制器的一般配置。第一个子控制器master显示了除了详细内容的其他可用内容,当列表项被选中时,其推出一个同级的控制器在导航控制器之上,所以用户可以看到详细内容。类似的,如果用户想看到更多的详细内容,这同级关系可以推动另一个视图控制器显示更多的详细的内容,当同级视图有一个定义良好的关系。同级关系经常直接或通过容器控制器相互协调。如图1-15所示。
图1-12模态关系
当A视图控制器想要执行一项任务时也会推出B视图控制器。A视图控制器负责推出B的这个行为,A配置了B视图控制器,并且获取信息从B视图控制器,最终销毁B。但是,虽然B视图控制器是被推出的,B视图控制器也会临时的被添加到窗口的视图层级内。
图1-13当一个视图控制器被推出后,它所占据的屏幕的区域是被一个称为显示上下文的视图控制器决定的。提供显示上下文的视图控制器并不需要有和被推出视图控制器一样的控制器。图1-14显示了一个和图1-13中被推出的视图控制器一样的视图控制层级。我们可以看Content视图控制器推出了Modal视图控制器,但是并没有提供显示上下文。相反,Content视图控制器是被Tab视图控制器推出的,因为这一点,尽管内容视图控制器仅覆盖选项卡视图控制器屏幕的一部分,但是Model视图控制器占据了选项卡视图控制器屏幕的全部。
图1-14内容控制器之间的控制流
多个视图控制器的app中,app的生命周期内需要经常创建或销毁视图控制器。视图控制器之间的相互通讯保证了良好的用户体验,这些关联关系代表了app中控制流。
绝大多数的,当一个是新的视图控制器初始化完成后会产生控制流。基于视图控制器的内容的操作会初始化另一个视图控制器,第一个视图控制器作为源视图控制器指挥着第二个视图控制器,即目标视图控制器。如果目标视图控制器需要显示数据给用户,通常是源视图控制器提供数据源。类似的,如果源视图控制器需要从目标视图控制器获取信息,目标视图控制器负有建立连接的责任在它们两者之间。
图1-15显示了一个最普通的关联关系
1)导航视图控制器的一个子控制器从导航控制器堆栈上推出了另外一个子控制器;
2)一个视图控制器提供另一个视图控制器;
3)一个视图控制器在弹窗中显示另一个视图控制器。
图1-15每个视图控制器都是被处理它的视图控制配置,当多个视图控制器一起工作,它们建立了一个通讯链。
目标视图控制器定义了每个链接之间的控制流,源视图控制器使用这个约定好的控制流。
1)目标视图控制器提供了用于配置属性数据和显示规则;
2)如果目标视图控制器需要和在通讯链中提供处理的视图控制器通讯,可以使用委托。如果源视图控制器需配置目标视图控制器的其他属性,源视图控制器同样也期望提供一个实现了委托协议的对象。
使用控制流约定的优点是可以在每对源控制器和目标控制器之间分工明确,当源视图控制器要求目标视图控制器执行一项任务时数据流需要沿着路径向下传递,目标视图控制器驱动着这个过程。例如,目标视图控制器可能需要显示一些特定的数据来自于源视图控制器。从另一个方向来讲,当是一个视图控制器需要提交数据到源视图控制器是数据流需要沿着路径向上传递。例如,任务执行完毕需要通讯。
同时,通过一致的实现这种控制流模型,可以确保目标视图控制器从不会知晓太多关于配置它们的源视图控制器.当目标视图控制器知道通讯链中上流的的视图控制器,就明白只有类实现委托协议。通过保持视图控制器互相了解太多,提高了单独的控制器的复用性。别人阅读你的代码,一个实现一致的控制流模型在任何一对控制器之间的通信路径都很容易一清二楚。