@import url(http://i.cnblogs.com/Load.ashx?type=style&file=SyntaxHighlighter.css);@import url(/css/cuteeditor.css);

View Controller用于管理app的各种资源,有时虽然View Controller被实例化,但仍不会在屏幕中显示。比如Navigation中的view controller,只有栈顶的元素才能显示。正因为如此,所以View Controller实现了复杂行为来管理view的load和unload操作。

1 VC初始化

当View Controller被初始化时,它首先创建和加载在其生命周期内都要使用的对象。同时View Controller一般不会创建View对象,且不会创建一些可视化的内容。对于那些创建或维护比较耗资源的对象,一般都采用赖加载。

当app在Launch阶段时,IOS只实例化main storyboard文件中的起始view controller(Initial View Controller),若后续需要更多的view controller,那么可以调用UIStoryboard类的instantiateViewControllerWithIdentifier方法来实例化storyboard文件中定义的view controller;若在storyboard文件中没有定义相应的view controller,则可按Objective-C传统的allocate 和 initialize方法进行实例化。

1.1 view展示

1) 获取view对象

若使用Storyboard方式定义View Controller和View时,那么当View Controller对象需要view对象时,UIKit会自动从Storyboard文件中加载相关的view对象,UIKit执行具体过程为:

a) 获取storyboard文件中的信息,进而实例化view

b) 连接所有outlets 和 actions;

c) 设置view controller的view属性root view(每个view controller都有一个主视图);

d) 调用view controller对象的awakeFromNib方法(若被实现),从而用户可以在这些方法中执行一些配置内容;

e) 调用view controller的viewDidLoad方法:通过该方法进行view的添加、删除、修改布局约束和加载数据。

2) 屏幕显示

在将view controller的view展示在屏幕之前,UIKit提供一些方法进行操作,UIKit将view展示在屏幕过程中执行如下操作:

a) 在view显示在屏幕之前,会调用view controller的viewWillAppear方法

b) 更新view的布局;

c) 将view展示在屏幕中;

d) 在view显示在屏幕之后,会调用view controller的viewDidAppear方法

1.2布局管理

当view的尺寸或位置发生改变时,UIKit会自动更新层次结构中的view布局。若使用Auto Layout来配置view,那么UIKit会根据当前的布局约束来更新布局。在UIKit更新view的布局过程中,会发送一些消息给用户,使得还有机会修改view的布局。其中UIKit更新的过程操作为:

a) 更新view或view controller的特征;

b) 调用view controller的viewWillLayoutSubviews方法

c) 调用当前UIPresentationController对象的containerViewWillLayoutSubviews方法

d) 调用view controller中的root view的layoutSubviews方法:该方法的默认实现是根据布局约束来计算新布局信息,并且它会递归调用层次结构中所有子view的layoutSubviews方法;

e) 将布局信息应用于所有view中;

f) 调用view controller的viewDidLayoutSubviews方法

g) 调用当前UIPresentationController对象的containerViewDidLayoutSubviews方法

正如上述的b)和f)中,可以在view controller的viewWillLayoutSubviews 和 viewDidLayoutSubviews方法中另外配置一些信息,从而可影响布局设置。即可在布局之前,添加或移除view,也可更新view的尺寸或位置,以及能更新布局约束或修改层次结构中相关属性;在布局之后,需要重新加载布局,从而做最后的更改。

2 view管理

在view controller中需要对对象进行引用管理,一般在表 21所示的UIViewController方法中创建内存或释放内存。

表 21 Places to allocate and deallocate memory

方法

功能

描述

Initialization

构造方法

创建新对象,初始化一些数据结构或属性的信息。

viewDidLoad

加载数据方法

通过这个方法来加载需要在view中显示的数据,并且在调用此方法时,要保证view对象存在和有好的状态。

didReceiveMemoryWarning

响应低内存消息方法

通过此方法来释放viewController的一些非重要对象。

dealloc

虚构方法

重载该方法来释放view controller对象的内存。

在一个View Controller对象的生命周期中,对View对象有两个重要的管理周期:load和unload。

2.1 加载

任何时候若其View对象不在内存中,而又被访问,那么View Controller对象将创建和初始化需要的View对象。并将加载的View对象赋值给自身(View Controller对象)的view属性。

如下是加载(load)view的过程:

1) 若View Controller对象中不存在view对象,而又被访问了view对象,那么将触发加载的过程。

2) View Controller对象将调用loadView方法,默认在该方法中实现如下两件事之一:

  • 若View Controller有一个关联的storyboard,则从storyboard文件中加载view;
  • 若View Controller没有关联的storyboard,则创建一个空的UIView对象,并将其赋值给View Controller的view属性。

3) View Controller对象将调用viewDidLoad方法,从而可在该方法中执行一些附件的操作,如初始化子类。

如图 21所示,是load一个view对象的过程,用户可以重载图中的loadView和viewDidLoad方法,从而执行一些附件的操作。比如可以另外添加一个视图的层次结构。

图 21 Loading a view into memory

2.2 卸载

只要app接收到低内存警告,那么View Controller对象将立即卸载(unload)view对象。在unload过程中,View Controller对象将释放view对象,并将该View Controller对象还原到最初状态,即无view对象状态。若成功释放了view对象,那么View Controller对象将一直保持无view状态,直到重新需要访问view对象,那么再重新加载view对象。

如下是view的卸载(unload)过程:

a) app接收到系统发送的低内存警告信息;

b) app中的每个View Controller对象都会调用didReceiveMemoryWarning方法,该方法的默认实现是释放view对象;

c) 如果不能安全释放view对象(如该view正处于屏幕中),那么其默认实现是直接返回;

d) View Controller对象将调用viewWillUnload方法,从而向那些将被移除view对象的所有子类发送消息。一般子类都重载viewWillUnload方法,从而来保存一些属性信息。

e) 将View Controller对象的view属性设置为nil。

f) View Controller对象将调用viewDidUnload方法向被移除view的子类发送消息。一般子类在该方法中释放强引用的指针。

如图 22所示是view被unload的过程:

图 22 Unloading a view from memory

3 实现Container VC

Container View Controller将多个Content View Controller结合为单一的层次结构窗口,即建立Container VC与Content VC之间的一种父子关系。Container VC管理Content VC的尺寸和位置,而Content VC自己管理其内部的view和控件。

3.1 Interface Builder方式

通过Interface Builder创建和配置Container View Controller比较简单。只需在Container View Controller的view中添加一个Container view控件,这个控件只是一个占位符,不具有可视化功能;然后从Container view控件中以Embed方式推出Content View Controller即可。如图 23和图 24所示的操作图和效果图。

图 23 操作图

图 24 运行效果图

3.2 Program方式

程序的方式比较复杂,但是控制的功能也比较多。

3.2.1 添加子VC

通过程序的方式,建立view controller之间的一种父子关系,可以按如下步骤完成:

a) 调用container view controller的addChildViewController方法;从而告诉UIKit由该 container VC来管理相应子view controller(content view controller)。

b) 将content VC的view添加到container view的层次结构中。

c) 在container view中为子content view添加一些布局约束(若需要)。

d) 调用子view controller的didMoveToParentViewController方法

如下所示是简单在container view controller添加一个子view controller的例子:

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

2     {

3         [self addChildViewController:content];

4         content.view.frame = [self frameForContentController];

5         [self.view addSubview:self.currentClientView];

6         [content didMoveToParentViewController:self];

7 }

3.2.2 移除子VC

为了移除container view controller中的子view controller,需按如下步骤完成:

a) 调用子view controller的willMoveToParentViewController方法,并传递一个nil参数。

b) 移除子content view在container view中配置的布局约束。

c) 通过调用子content view的removeFromSuperview方法,将子content view从container view的层次结构中移除。

d) 调用子view controller的removeFromParentViewController方法来终止container与content之间的父子关系。

如下所示:

1     - (void) hideContentController: (UIViewController*) content

2     {

3         [content willMoveToParentViewController:nil];

4         [content.view removeFromSuperview];

5         [content removeFromParentViewController];

6     }

3.2.3 转换子VC

可以在container view controller中切换view controller,同时还可在切换的过程中添加一些动画,但在切换之前必须保证切换的view controller需为container view controller的子view controller。

如下所示,是切换两个view controller:

 1     - (void)cycleFromViewController: (UIViewController*) oldVC toViewController: (UIViewController*) newVC

 2     {

 3         // Prepare the two view controllers for the change.

 4         [oldVC willMoveToParentViewController:nil];

 5         [self addChildViewController:newVC];

 6              

 7         // Get the start frame of the new view controller and the end frame

 8         // for the old view controller. Both rectangles are offscreen.

 9         newVC.view.frame = [self newViewStartFrame];

10         CGRect endFrame = [self oldViewEndFrame];

11              

12         // Queue up the transition animation.

13          [self transitionFromViewController: oldVC toViewController: newVC

14                 duration: 0.25 options:0

15                 animations:^{

16                 // Animate the views to their final positions.

17                         newVC.view.frame = oldVC.view.frame;

18                         oldVC.view.frame = endFrame;

19                 }

20                 completion:^(BOOL finished) {

21                     // Remove the old view controller and send the final

22                     // notification to the new view controller.

23                      [oldVC removeFromParentViewController];

24                      [newVC didMoveToParentViewController:self];

25           }];

26     }

iOS UIKit:viewController之定义(2)的更多相关文章

  1. iOS UIKit:viewController之动画(5)

    当弹出一个view controller时,UIKit提供了一些标准转换动画,并且也支持用户自定义的动画效果. 1 UIView动画 UIView是自带动画实现功能,其中有两种方式实现:        ...

  2. iOS UIKit:viewController之层次结构(1)

    ViewController是iOS应用程序中重要的部分,是应用程序数据和视图之间的重要桥梁.且应用程序至少有一个view controller.每个view controller对象都负责和管理一个 ...

  3. iOS UIKit:viewController之Present (3)

    弹出和转换view controller技术是一种快速且简单的方式将新view content展示在屏幕中.目前有两种方式弹出新的view controller:Present方式和segues方式. ...

  4. iOS UIKit:viewController之Segues (4)

    @import url(http://i.cnblogs.com/Load.ashx?type=style&file=SyntaxHighlighter.css);@import url(/c ...

  5. iOS UIKit:view

    @import url(http://i.cnblogs.com/Load.ashx?type=style&file=SyntaxHighlighter.css); @import url(/ ...

  6. iOS UIKit Dynamics入门 UIKit动力学,实现重力、连接、碰撞、悬挂等动画效果

    本文为转载文章 版权归原文所有 什么是UIKit动力学(UIKit Dynamics) 其实就是UIKit的一套动画和交互体系.我们现在进行UI动画基本都是使用CoreAnimation或者UIVie ...

  7. [Android开发学iOS系列] ViewController

    iOS ViewController 写UIKit的代码, ViewController是离不开的. 本文试图讲讲它的基本知识, 不是很深入且有点杂乱, 供初级选手和跨技术栈同学参考. What is ...

  8. iOS UIKit:TableView之编辑模式(3)

    一般table view有编辑模式和正常模式,当table view进入编辑模式时,会在row的左边显示编辑和重排控件,如图 42所示的编辑模式时的控件布局:左边的editing control有表 ...

  9. iOS UIKit:TableView之单元格配置(2)

    Table View是UITableView类的实例对象,其是使用节(section)来描述信息的一种滚动列表.但与普通的表格不同,tableView只有一行,且只能在垂直方向进行滚动.tableVi ...

随机推荐

  1. WCF SOAP

    WCF SOAP服务端解析 ASP.NET Core中间件(Middleware)进阶学习实现SOAP 解析. 本篇将介绍实现ASP.NET Core SOAP服务端解析,而不是ASP.NET Cor ...

  2. JS贪吃蛇游戏

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http ...

  3. BASLER 镜头选型白皮书

    本文翻译自Basler镜头选型白皮书 有许多方法来进行镜头选型.本文将会讨论其中的指导原则,以帮助你在项目中选择合适的镜头.我们将讨论许多镜头的基本概念,比如镜头接口.图像大小.放大率.焦距.F数和光 ...

  4. 提升网站用户体验—WebP 图片的高效使用

    一.WebP 的由来 现代图像压缩技术对我们的生活方式影响很大.数码相机能将上千张高质量图片存储到一张内存卡里.智能手机可以与邻近设备快速分享高分辨率的图片.网站与手机等移动设备能快速展示各种富媒体. ...

  5. 【HDU3065】 病毒侵袭持续中(AC自动机)

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission( ...

  6. 关于C语言中用Keil软件制作Lib库文件的几点经验

    1.关于制止LIB库文件的几点经验 1. 一个工程如何生成lib文件: 2. 一个生成lib文件的工程可以调用这个工程中不存在的函数,只需要在.h文件中声明这些不存在函数的原型,然后在调用这个lib文 ...

  7. Buddy system伙伴分配器实现

    wikipedia:http://en.wikipedia.org/wiki/Buddy_memory_allocation The buddy memory allocation technique ...

  8. 内存管理(memory allocation内存分配)

    Memory management is the act of managing computer memory. The essential requirement of memory manage ...

  9. Spring dataSource

    1.何为dataSource DataSource 接口是 JDBC 2.0 API 中的新增内容,它提供了连接到数据源的另一种方法. 作为 DriverManager 工具的替代项,DataSour ...

  10. IPCS资源

    ipcrm用法 ipcrm -M shmkey  移除用shmkey创建的共享内存段 ipcrm -m shmid    移除用shmid标识的共享内存段 ipcrm -Q msgkey  移除用ms ...