视图控制器应该在MVC设计模式中扮演控制层(C)的角色,UIViewController的职责对内管理与之关联的View,对外跟其他UIViewController通信和协调。一个视图控制器管理一个视图(它可以有子视图),其view属性指向它所管理的视图。UIViewController类可以有子类,可以使用一个系统的UIViewController子类或者直接自己创建一个UIViewController的子类。

使用代码创建控制器和视图。

开始创建一个基于窗口的Empty Application的项目。

创建一个视图控制器子类:File–New–New File(Command+N)然后选择Objective-C class,命名为RootViewController然后在subclass of中输入UIViewController,单击Next按钮保存。

现在有一个RootViewController类,接着编辑它的代码。一个视图控制器负责获得或创建它自己的视图。如果视图控制器手动创建它的视图,必须重载UIViewController类的loadView方法。下面给视图设置一个颜色,放一个“Hello World!”标签在这个视图中。

@interface RootViewController ()

@end

@implementation RootViewController

-(void) loadView{

   // applicationFrame是整个可见区域,不包括状态栏
UIView* view = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];
//设置view的颜色
view.backgroundColor = [UIColor greenColor]; //添加一个标签
UILabel* label = [[UILabel alloc] init];
label.text=@"Hello World!"; //自适应大小
; //居中
label.center = CGPointMake(CGRectGetMidX(view.bounds), CGRectGetMidY(view.bounds)); //添加到view
[view addSubview:label]; //设置self.view = view这样视图控制器就可以管理这个视图了,如果实现了loadView那么就必须设置self.view
self.view = view;
} ...
@end

视图控制器已经准备好,现在准备使用它。我们要调整一下应用程序的委托类(AppDelegate),在应用程序委托类的头文件中,声明视图控制器属性。

@property (strong, nonatomic) RootViewController *rootViewController;

在应用程序委托的实现代码中,我们导入”RootViewController.h”,在应用程序委托的application: didFinishLaunchingWithOptions方法中创建新的视图控制器,并把视图放到界面中。

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
self.window.backgroundColor = [UIColor whiteColor]; //创建视图控制器
RootViewController* theRVC = [[RootViewController alloc]init];
self.rootViewController = theRVC; //不仅要创建视图,还必须把视图放到界面中
[self.window addSubview:self.rootViewController.view]; [self.window makeKeyAndVisible];
return YES;
}

编译并运行应用程序,运行结果如下图所示。

还有一种简单的方法是使用UIWindow的rootViewController属性。这样就不需要在应用程序委托类的头文件中,声明视图控制器属性。也不需要把视图作为子视图添加到窗口上。当给一个rootViewController属性分配一个UIViewController实例时,它会自动获得UIVIewController的视图,并使它成为窗口的唯一子视图。

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
self.window.backgroundColor = [UIColor whiteColor]; //创建视图控制器
RootViewController* theRVC = [[RootViewController alloc]init]; // self.rootViewController = theRVC;
//不仅要创建视图,还必须把视图放到界面中
//[self.window addSubview:self.rootViewController.view]; //这行代码与上面注释掉的两行代码的效果是一样的。
self.window.rootViewController = theRVC; [self.window makeKeyAndVisible];
return YES;
}

窗口的根视图控制器是全局可用的,如果需要获取根视图控制器,可以使用下面的代码:

UIViewController* rootController = [[[UIApplication sharedApplication] keyWindow] rootViewController];
在nib文件中创建视图控制器

在nib文件中设计和维护一个复杂的用户界面比在代码中创建更方便、简单。

Command+N–User Interface–View,命名为View.xib

编辑View.xib,更改File’s Owner的类为RootViewController。这将产生一个view输出口,并把它连接到视图上。(在File’s Owner上单击右键,点击view不放,然后拖动到view上。)

然后修改应用程序委托的相关代码:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
self.window.backgroundColor = [UIColor whiteColor]; //使用nib文件创建视图控制器
RootViewController* theRVC = [[RootViewController alloc]initWithNibName:@"View" bundle:nil]; self.window.rootViewController = theRVC; [self.window makeKeyAndVisible]; return YES;
}
UIViewController的初始化
  • 程序请求controller的view
  • 如果view在内存中,则直接加载。相反,如果不存在,则UIViewController调用loadView方法
  • loadView方法执行如下操作:
    • 如果你重载了这个方法,则必须创建必要的view并且将一个非nil值传给UIViewController的view属性。
    • 如果你没有重载这个函数,UIViewController会默认使用UIViewController的nibName和nibBundle属性尝试从nib文件加载view。如果没有找到nib文件,则ViewController会通过以下两个步骤找到与其关联的nib。
      A 如果类名包含Controller,例如ViewController的类名是MyViewController,则查找是否存在MyView.nib;
      B 找跟ViewController类名一样的文件,例如MyViewController,则查找是否存在MyViewController.nib。
    • 如果没有可用的nib文件,那么它创建一个空的UIView作为它的view。
  • UIViewController调用viewDidLoad来执行一些加载时任务。

当需要显示或者访问view属性时,view没有创建的话,VC就会调用loadView方法,在这个时候会创建一个view并将其赋给VC.view属性。紧接着就会调用VC的viewDidLoad方法,这个时候VC.view保证是有值的,可以做进一步的初始化操作,例如添加一些subview。注意:定制VC时,如果覆盖loadView方法,不需要调用[super loadView]方法。

UIViewController卸载View的步骤.

对于与之关联的View,UIViewController总是在需要的时候才加载视图,并在不需要的时候卸载视图,所以也同时担当了管理应用资源的责任。理解UIViewController的生命周期(LifeCycle),能够有效地管理应用资源。Controller的view最好在需要显示时再去加载,并且在系统发出内存警告时释放比必要的view及相关的数据对象。UIViewController卸载View的步骤如下:

  • 程序收到内存警告
  • 每个UIViewController调用didReceiveMemoryWarning, 默认会安全地释放掉view
  • 如果UIViewController释放掉了它的view,它会调用viewDidUnload。可以重载这个方法来进行额外的清理工作。

官方文档:The View Controller Life Cycle

iOS开发之视图控制器(UIViewController)的更多相关文章

  1. iOS开发中视图控制器ViewControllers之间的数据传递

    iOS开发中视图控制器ViewControllers之间的数据传递 这里我们用一个demo来说明ios是如何在视图控制器之间传递重要的参数的.本文先从手写UI来讨论,在下一篇文章中讨论在storybo ...

  2. iOS开发系列--视图切换

    概述 在iOS开发中视图的切换是很频繁的,独立的视图应用在实际开发过程中并不常见,除非你的应用足够简单.在iOS开发中常用的视图切换有三种,今天我们将一一介绍: UITabBarController ...

  3. iOS开发UI篇—控制器的创建

    iOS开发UI篇—控制器的创建 说明:控制器有三种创建方式,下面一一进行说明. 一.第一种创建方式(使用代码直接创建) 1.创建一个空的IOS项目. 2.为项目添加一个控制器类. 3.直接在代理方法中 ...

  4. iOS开发UI篇—控制器的View的创建

    iOS开发UI篇—控制器的View的创建 一.6种创建控制器View的方式 #import "NJAppDelegate.h" #import "NJViewContro ...

  5. Swift - iOS中各种视图控制器(View Controller)的介绍

    在iOS中,不同的视图控制器负责不同的功能,采用不同的风格向用户呈现信息.下面对各个视图控制器做个总结: 1,标准视图控制器 - View Controller 这个控制器只是用来呈现内容.通常会用来 ...

  6. IOS开发之视图和视图控制器

    视图(View), 视图控制器(ViewController)是IOS开发UI部分比较重要的东西.在学习视图这一块的东西的时候,感觉和Java Swing中的Panel差不多.在UIKit框架中都有一 ...

  7. IOS开发-表视图LV3导航控制器

    学到这里感觉有点难了,其实这篇文章再草稿箱里放了好久了~ 最近对于学习的热情下降了.这不行-抓紧学习走起! 在这一章节的学习中主要针对导航控制器及表视图来建立多视图的应用, 首先要了解一些概念-- 1 ...

  8. 学习笔记:iOS 视图控制器(UIViewController)剖析

    转自:http://www.cnblogs.com/martin1009/archive/2012/06/01/2531136.html 视图控制器在iOS编程中占据非常重要的位置,因此我们一定要掌握 ...

  9. iOS开发UINavigation——导航控制器UINavigationController

    iOS开发UINavigation系列一——导航栏UINavigtionBar摘要iOS中的导航条可以附着于导航控制器之中使用,也可以在controller中单独使用,这篇博客,主要讨论有关导航栏的使 ...

随机推荐

  1. bzoj 1007 : [HNOI2008]水平可见直线 计算几何

    题目链接 给出n条直线, 问从y轴上方向下看, 能看到哪些直线, 输出这些直线的编号. 首先我们按斜率排序, 然后依次加入一个栈里面, 如果刚加入的直线, 和之前的那条直线斜率相等, 那么显然之前的会 ...

  2. Python学习之字符串函数

    下面是在看python核心编程中序列字符串中提到的一些函数,根据自己的学习理解总结了下,方便日后用到的时候查看.    1.string.capitalize() 把字符串的第一个字符大写 例子:   ...

  3. Protel99se教程四:将SCH转为PCB文件

    本节课,我们介绍,如何快速的将绘制好的SCH文件转为PCB文件,首先,我们打开刚开始时我们绘制的SCH原理图,我们可以使用protel99se菜单栏的view-Fit All Objects命令,以查 ...

  4. cocos2d-x中的尺寸之三

    通过上面两个文章的分析,我们在这个博文里做个总结: CCEGLView::getFrameSize()返回的是窗口相对于屏幕像素的尺寸,这个尺寸,只要窗口没变化,值就不会变化 CCDirector:: ...

  5. vmware 几种联网的方式,怎样实现虚拟机上网

    我的pc有一个IP地址是可以訪问网络的,那么如何让VM可以共享我的IP地址,也能上网呢.今天在摸索中实现了,详细的配置例如以下: 1,首先将VM的网卡net8启用: 2,然后将VM的网卡设置为VMne ...

  6. Android中的一些基础知识(三)

    最近在回顾Android的基础知识,就把一些常见的知识点整理一下,以后忘了也可以翻出来看一看. 在TextView中显示图像(使用< img>标签) 在TextView中显示图片的方法有许 ...

  7. 融合python2和python3

    很多情况下你可能会想要开发一个程序能同时在python2和python3中运行. 想象一下你开发了一个模块,成百上千的人都在使用它,但不是所有的用户都同时使用python 2和3.这种情况下你有两个选 ...

  8. Node.js学习笔记1(简介)

            1.什么是Node.js?         Node.js,或者 Node,是一个可以让 JavaScript 运行在服务器端的平台.它可以让 JavaScript 脱离浏览器的束缚运 ...

  9. Binary Tree Preorder Traversal and Binary Tree Postorder Traversal

    Binary Tree Preorder Traversal Given a binary tree, return the preorder traversal of its nodes' valu ...

  10. shell学习之用户管理和文件属性

    1.组和用户的添加 添加组: groupadd [-g gid [-o]] [-r] [-f] group 示例: groupadd -g testgoup1 #添加组testgroup1,同时指定g ...