1.mvc架构模式与视图控制器的作用
在iOS系统上运行的应用程序遵守MVC的软件架构模式,分为三个基本部分:模型(Model)、视图(View)和控制器(Controller)。
MVC模式最早由Trygve Reenskaug在1974年提出,是施乐帕罗奥多研究中心(Xerox PARC)在20世纪80年代为程序语言Smalltalk发明的一种软件设计模式。MVC模式的目的是实现一种动态的程序设计,使后续对程序的修改和扩展简化,并且使程序某一部分的重复利用成为可能。除此之外,此模式通过对复杂度的简化,使程序结构更加直观。软件系统通过对自身基本部分分离的同时也赋予了各个基本部分应有的功能。
控制器Controller:负责转发请求,对请求进行处理。
视图View:界面设计人员进行图形界面设计。
模型Model:程序员编写程序应有的功能、数据库专家进行数据管理和数据库设计。
在iOS的应用程序中,MVC架构模式将应用程序的屏幕对象的外观和行为区分开来。屏幕上的对象如按钮,本身没有任何内在含义,它能实现的所有操作都是通过视图控制器来实现的。视图控制器是桥梁,将用户操作和应用程序中的目标方法联系起来,目标方法又读取和保存数据到应用程序中的某个数据模型里。
这是一个极其简单的iOS应用程序的架构模式。在MVC中,视图控制器的角色看成控制器,但也能看成是视图,因为它是控制视图显示的重要组成部分。
一、视图(View)
在iOS应用程序创建时,所使用的视图组件是由UIView 类的子类及与其相关的UIViewController类提供,它们分别负责定义和放置屏幕元素。UIViewController类不是MVC 模式中的控制器角色,这点和命名略有出入,就理解成这是控制视图的一个类。它负责对屏幕的各项元素进行布局。
但是,每个UIViewController子类都实现了自己的loadView方法。该方法对视图控制器的所属视图进行布局,并建立所有的触发、回调和委托。从这个角度看,它又算一个控制器。
二、控制器(Controller)
在iOS应用程序中,控制器的行为通过这三个技术来实现,分别是委托、目标操作和通知。
1、目标操作(target action)
它是重定向用户交互的一种较低级的方式,基本上只有在实现UIControl类的子类时,我们会遇到它们。
例如,在应用的视图界面上有一个按钮,"touch up inside",就是将执行target配置的对象和action配置的方法。
视图控制器类的代码是这样的:
UIBarButtonItem *barListBtn = [[UIBarButtonItem alloc] initWithBarButtonSystemItem: UIBarButtonSystemItemAdd target:self action:@selector(getTruckStopListAction)];
self.navigationItem.rightBarButtonItem = barListBtn;
[barListBtn release];
代码中定义的action是@selector(getTruckStopListAction),定义的target是视图控制器类本身即self。
在视图控制器类中应该有一个已实现的getTruckStopListAction方法,按钮"touch up inside"时触发的就是这个方法。这个方法可以看着是MVC架构模式中的控制器角色,它的定义代码可以按照需求随时修改。
这就是target-action模式。
如果target不是self,而是其他的类,那么在其他的类要实现这个action所配置的方法。这个类就是一个纯种的MVC架构模式的控制器。不像现在和视图控制器类参杂在一起,搞得不知道视图控制器类算MVC架构模式的控制器还是MVC架构模式的视图。
2.UIViewController的生命周期
A.创建UIViewController
我们可以直接手写代码生成一个UIViewController也可以通过XIB生成一个UIViewController。
通过 -(id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil初始化ViewController。但是此时本视图中的控件都没有添加到视图中,此时通过IBoult关联的IB控件值为空。
B.UIViewController初始化完毕
如果用IB生成的ViewController,当执行- (void)viewDidLoad这个方法的时候,说明此ViewController的视图已经绘制成功。我建议在此方法中添加视图修改和添加新视图的一些方法。
C.UIViewController的销毁
当UIViewController里面的视图全部移除的时候,此时UIViewController彻底从内存中销毁。
D.内存警告
当多个ViewController相互叠加的时候,程序内存可能不够用,此时系统会发送内存警告。则会执行didReceiveMemoryWarning这个方法,ViewController中的view不是激活状态的View,同时会执行viewDidUnload这个方法,此controllerView的视图再次被激活的时候,则重新调用2步骤。
3.设备旋转的处理方法
某些情况下,不强制的给用户唯一的屏幕角度给用户。这样用户可以旋转手机得到不同的视觉体验。
最简单的就是safari,横看竖看都可以。
这时需要捕捉用户的屏幕旋转事件并处理。很简单,才两步。比把大象装冰箱都简单。
下面是代码:
1 - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
2 {
3 self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
4 if (self) {
5 [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
6[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(orientationChanged:)
7 name:UIDeviceOrientationDidChangeNotification
8 object:[UIDevice currentDevice]];
9 }
10 return self;
11 }
在ViewController初始化或者viewDidLoad方法中加入Notification就可以。很显然,Post Notification的事苹果的SDK已经为我们处理了。我们代码中要做的就是处理发送来的Notification。
添加好Notification的Observer后就剩添加具体的处理方法了。这里就是orientationChanged。
1 - (void)orientationChanged:(NSNotification *)notification{
2 UIDevice * device = notification.object;
3 switch(device.orientation)
4 {
5 case UIDeviceOrientationPortrait:
6 /* start special animation */
7 break;
8
9 case UIDeviceOrientationPortraitUpsideDown:
10 /* start special animation */
11 break;
12
13 default:
14 break;
15 };
16 }
接下来就在switch-case语句里针对没一种屏幕可能的角度添加你的处理代码吧。