实现一个容器视图控制器(上)

来源:互联网 发布:淘宝发布宝贝数量 编辑:程序博客网 时间:2024/05/16 10:24

什么是容器视图控制器(ContainerView Controller)?苹果官方文档定义:Container view controllers are a way to combine the contentfrom multiple view controllers into a single user interface.容器视图控制器可以将具有多个视图控制器的内容统一到一个界面上,说简单点就是它可以管理其它View ControllerContainer View Controller经常用来做导航或者创建新界面。在UIKit中苹果已经定义好了几个Container View Controller如:UINavigationController, UITabBarControllerUISplitViewController,他们的功能就是帮助你切换视图。

 

 

设计ContainerView Controller

在大部分情况下,Container View Controller和普通View Controller一样,它管理一个root view和其他一些内容,不同的是Container View Controller的content是从其他view controller中获取的。其他view controller的view嵌套在container view controller 中的view中。Container View Controller设置嵌套view的大小和位置,但是这些嵌套view 的原来的view controller 仍然可以管理它们自己的view。下面的图可以解释这种关系。

当设计自己的Container View Controller时,需要理解container和它包含的view controllers的关系。这些关系可以让你知道这些view的内容是否应该在屏幕上显示,可以帮助你管理这些view controllers。在设计过程中,问自己一些下面的问题:

l  Container扮演了什么角色?它的子视图扮演了什么角色?

l  多少个子视图可以同时显示?

l  兄弟视图之间的关系是什么?

l  Child View Controllers如何添加到容器中?如何从容器中移除?

l  子视图的大小和位置可以改变吗?在什么样的条件下可以做这些改变?

l  Container自己提供了用来装饰或者导航相关的view了吗?

l  Container以什么样的方式和它的children通信?container需要将具体的事件通知给children还是通过在UIViewController中定义的标准方式?

l  Container 可以被配置成不同样式吗?如果可以,怎么配置?

 

 

在定义了各种对象的角色之后,实现Container View Controller是相对简单的。UIKit唯一的要求就是:你建立一个parent-child关系,在Container View Controller和其他child view controllers之间。Parent-child关系确保children能收到所有相关的系统消息。除此之外,大部分工作在布局和管理包含的view上,这对于每个container来说是不一样的。你可以将view放在container区域的任何地方,可以任意设置view 的大小。你可以添加个性化view到view层次结构中,用来装饰或者辅助导航。

 

例子:Navigation Controller

UINavigationController对象通过分层数据集来支持导航。导航界面每次只显示一个child view controller。界面顶部的导航栏显示当前view在数据集中的层次,并显示一个后退按钮用来回退到上一层。在当前视图中进一步导航则由child view controller完成,子视图可以包含表或者按钮。

 

Child view controllers之间的导航由navigation controller和child view controller共同管理。当用户点击了child view controller上的button或表中的一行后,child请求navigation controller放一个新的view controller到界面上。Child负责新的view controller的内容的配置,但是navigation controller负责视图切换的动画。Navigation controller同时也管理导航栏,导航栏显示一个后退button用来取消显示顶层view controller。

 

下图显示了navigation controller和它的views之间的结构。大部分显示区域被顶层view占据,仅有一小部分用来放置navigation bar。

 

Navigation controller一次仅显示一个child view,navigation controller会重新设置view的大小,以适应可用空间。

 

 

例子: Split ViewController

 

一个UISplitViewController对象显示两个view controllers的内容,在master-detail模式下。在这种模式下,master viewcontroller的内容决定显示哪些详细内容。两个view controller的可显示性是可以配置的,但是也受当前环境的控制。在正常的水平状态下,split view controller可以显示并排显示两个view controller(master和 detail),或者根据需要隐藏或显示master view。在紧凑(compact)环境下,split view controller仅显示一个view controller。

 

下图展示了分割视图界面和正常水平状态下的显示视图。Split view controller仅有默认视图。在这个例子中,两个子视图并排显示。子视图的大小、master view 的可显示性都是可以设置的。

 

 

在Interface Builder中配置容器

 

创建一个parent-child关系的container:添加一个container view到storyboard上,如下图所示。Container view展示child view controller的内容。用container view来设置子视图的大小和位置。

 

 

当你加载一个view controller和container view时,Interface Bulider会帮你加载这些child view 的view controller。子视图必须和父视图一起实例化,这样才能建立合适的parent-child关系。

 

如果你不用Interface Builder设置parent-child关系,你就必须用代码将child添加到container view controller中,接下来将描述如何实现。

 

实现个性化Container View Controller

 

为了实现一个Container View Controller,你必须知道你的View Controller和它的child view controllers之间的关系。在你能管理所有的child viewcontrollers的视图之前,你需要建立这样的parent-child关系。这样做让UIKit知道你的view controller 正在管理子视图的大小和位置。你可以通过Interface Builder或者代码来创建这种关系。当用代码创建这种关系的时候,你需要明确的添加或移除child view controller。

 

 

 

添加Child View Controller到内容

 

添加child viewcontroller,需要按照如下步骤来做:

 

1.   调用container view controller的 addChildViewController:方法,将child view controller添加进来,这个方法告诉UIKit你的container view controller正在管理child view controller的view。

2.   将子视图的根视图添加到container的view结构中

在这个操作中不要忘了设置子视图的大小和位置

3.   添加约束以管理子视图的大小和位置

4.   调用child view controller的didMoveToParentViewController:方法。


以上步骤展示了如何将child view controller嵌入到container中。在建立了parent-child关系之后,container设置child view的大小和位置,并将其加入到container的view层次结构中。设置child’s view的窗口大小很重要,确保view能够正确的在container中显示出来。在添加view 之后,container调用child view controller的didmoveToParentViewController:方法,给child viewcontroller一个机会来响应view拥有关系的变化。

 

简单的代码例子:

-   (void)displayContentController: (UIViewController)* content{

-   [selfaddChildViewController:content];

-   Content.view.frame = [selfframeForContentController];

-   [self.viewaddSubView:self.currentClientView];

-   [contentdidMoveToParentViewController:self];

-   }

 

你可能为疑问为什么没有调用child的willMoveToParentViewController:方法,因为AddChildViewController会调用child的willMoveToParentViewController:方法,因此不必在显式调用。

0 0
原创粉丝点击