#1. 创建控制器的方式
控制器首先应该设置自身的class
设置所监控的View(控制器的view是延迟加载的, 用到时加载)
控制器的view加载完毕后会调用viewDidLoad方法
##1.1. 直接创建
直接通过alloc 和 init 创建控制器
1
2
3
4
5
6
7
8
9
10
11
12
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window.backgroundColor = [UIColor whiteColor];
ViewController *one = [[ViewController alloc] init];
one.view.backgroundColor = [UIColor blueColor];
self.window.rootViewController = one;
[self.window makeKeyAndVisible];
return YES;
}
##1.2 通过storyboard创建
自己创建的stroyboard,需要设置一项Initial View Control 项目设置中设置了Main为Main interface, 所做的事情
创建window
加载storyboard, 并且创建初始化控制器
显示窗口
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:@"red" ];
self.window.rootViewController = vc;
3. 显示窗口
[self.window makeKeyAndVisible];
return YES;
}
##1.3. Xib创建方式
1
2
3
4
5
6
7
8
9
10
11
12
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window.backgroundColor = [UIColor whiteColor];
ThreeViewController *three = [[ThreeViewController alloc] initWithNibName:@"Three" bundle:nil];
self.window.rootViewController = three;
[self.window makeKeyAndVisible];
return YES;
}
#2. ViewController的view创建(重要)
实现loadView()后, 会忽略storyboard和xib, 会首先检测loadView, 这个方法用来自定义View,
控制器view是延迟加载的, 用到时再加载(控制器view加载完毕后调用viewDidLoad方法
一旦加载view马上调用loadView()->viewDidLoad()->返回view被使用
View的加载过程:
UIView
凡是继承自UIButton都可以直接使用addsubview监听事件
#3. 多控制器
用一个控制器管理其他多个控制器
如果控制器A管理控制器B,C,D, 控制器A称为B, C, D的父控制器(B,C,D称为控制器A的子控制器)
IOS提供了2个比较特殊的控制器
UINavigationController
UITabBarController
UINavigationController
状态栏高度20, 导航栏高亮为44, 一个导航控制器只有一个导航栏
1
2
3
4
5
6
7
- (void )applicationDidBecomeActive:(UIApplication *)application {
UINavigationController *nav = (UINavigationController *)self.window.rootViewController;
NSLog(@"%@" , NSStringFromCGRect(nav.navigationBar.frame));
}
导航栏使用栈操作, 将子控制器push到栈(@property(nonatomic,copy) NSArray *viewControllers;)中(控制器创建view并显示出来)显示导航控制器上的永远是栈顶控制器
UINavigationController的使用步骤
初始化UINavigationController
设置UIWindow的rootViewController为UINavigationController
根据具体情况,通过push方法添加对应个数的子控制器
某些情况下移除控制器
1
2
3
4
5
6
- (UIViewController *)popViewControllerAnimated:(BOOL)animated;
- (NSArray *)popToViewController:(UIViewController *)viewController animated:(BOOL)animated;
- (NSArray *)popToRootViewControllerAnimated:(BOOL)animated;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen]bounds]];
self.window.backgroundColor = [UIColor whiteColor];
UINavigationController *nav = [[UINavigationController alloc] init];
OneViewController *one = [[OneViewController alloc] init];
[nav pushViewController:one animated:YES];
UIViewController *vc1 = [[UIViewController alloc] init];
vc1.view.backgroundColor = [UIColor redColor];
[nav pushViewController:vc1 animated:YES];
self.window.rootViewController = nav;
[self.window makeKeyAndVisible];
return YES;
}
##3.1. 修改导航栏
导航栏的内容由栈顶控制器的navigationItem属性决定
UINavigationItem有以下属性影响着导航栏的内容:
1
2
3
4
5
6
7
8
9
10
@property(nonatomic,retain) UIBarButtonItem *backBarButtonItem;
@property(nonatomic,retain) UIView *titleView;
@property(nonatomic,copy) NSString *title;
@property(nonatomic,retain) UIBarButtonItem *leftBarButtonItem;
UIBarButtonItem *rightBarButtonItem 右上角的视图
@property(nonatomic,retain) UIBarButtonItem *rightBarButtonItem;
1
2
3
4
5
6
7
8
9
- (void )viewDidLoad {
[super viewDidLoad];
self.navigationItem.title = @"第一个控制器" ;
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCamera target:nil action:nil];
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemEdit target:nil action:nil];
self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc]initWithTitle:@"返回" style:UIBarButtonItemStyleDone target:nil action:nil];
}
##3.2. 界面一览
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
- (void )applicationDidBecomeActive:(UIApplication *)application
{
NSString *xml = [self digView:self.window];
[xml writeToFile:@"/Users/aplle/Documents/window.xml" atomically:YES];
}
- (NSString *)digView:(UIView *)view
{
if ([view isKindOfClass:[UITableViewCell class]]) return @"" ;
NSMutableString *xml = [NSMutableString string ];
[xml appendFormat:@"<%@ frame=\"%@\"" , view.class, NSStringFromCGRect(view.frame)];
if (!CGPointEqualToPoint(view.bounds.origin, CGPointZero)) {
[xml appendFormat:@" bounds=\"%@\"" , NSStringFromCGRect(view.bounds)];
}
if ([view isKindOfClass:[UIScrollView class]]) {
UIScrollView *scroll = (UIScrollView *)view;
if (!UIEdgeInsetsEqualToEdgeInsets(UIEdgeInsetsZero, scroll.contentInset)) {
[xml appendFormat:@" contentInset=\"%@\"" , NSStringFromUIEdgeInsets(scroll.contentInset)];
}
}
if (view.subviews.count == 0 ) {
[xml appendString:@" />" ];
return xml;
} else {
[xml appendString:@">" ];
}
for (UIView *child in view.subviews) {
NSString *childXml = [self digView:child];
[xml appendString:childXml];
}
[xml appendFormat:@"</%@>" , view.class];
return xml;
}
UIWindow(UINavigationController的View(栈顶控制器的View(状态栏和导航栏)))不同于IOS6
##3.3. 控制器的生命周期
循环的生命周期:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
* view加载完毕
*/
- (void )viewDidLoad
{
[super viewDidLoad];
NSLog(@"MJOneViewController-viewDidLoad" );
}
* view即将显示到window上
*
*/
- (void )viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
NSLog(@"MJOneViewController-viewWillAppear" );
}
* view显示完毕(已经显示到窗口)
*/
- (void )viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
NSLog(@"MJOneViewController-viewDidAppear" );
}
* view即将从window上移除(即将看不见)
*
*/
- (void )viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
NSLog(@"MJOneViewController-viewWillDisappear" );
}
* view从window上完全移除(完全看不见)
*
*/
- (void )viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
NSLog(@"MJOneViewController-viewDidDisappear" );
}
* view即将销毁的时候调用
*/
- (void )viewWillUnload
{
[super viewWillUnload];
}
* view销毁完毕的时候调用
*/
- (void )viewDidUnload
{
[super viewDidUnload];
self.apps = nil;
self.persons = nil;
}
* 当接收到内存警告的时候
*/
- (void )didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
内存警告处理过程:
#4. storyboard的创建导航控制器步骤
删除已经创建的UIView Controller, 重新创建UINavigationController
创建新的UIView Controller, 设置class为自定义的ViewController类
在UINavigationController上双击,设置其rootViewcontroller为新创建的UIView Controller
可以直接在可视化界面上修改导航栏的样式或者添加push.
#5. UIView和UIViewController区别
UIViewController是视图控制器, 而UIView是视图, UIViewController用于控制UIView。
可以认为UIViewController就是一个相框, 而UIView就是一个相片, 相框可以随时随地的拿走这个相片而换另外一张相片, 或者在这张相片上加一个新的相片, 而相片却不能操纵相框的.
UIView用于向用户展示表现的内容, 并接受用户的交互
UIViewController相当于导演, 按照计划编排属下的UIView以何种形式展现.UIVewController的另一个功能是处理用户交互操作, UIViewController本身是不知道用户交互的,这就需要UIView将用户的交互操作(例如:touchesBegintouchesMoved)传递上来。一般常用的两种方法完成这种传递:
[self nextResponder] touchesBegin:touches…
使用Notification
如果UIViewController得到了用户的输入, 那么它应该对UIView做些改变以响应用户的输入, 这里要注意UIViewController应该只改变UIView的表现, 而不应该处理其它事情, 更多的操作通过Delegate来进行
UIView是一个视图, UIViewController是一个控制器, 每一个viewController管理着一个view