UI基础 - UIViewController

■ 简言

1. UIViewController 负责根视图上面所有子视图的一切事物、检测设备的旋转和内存的警告的发生!其生命周期如下

当创建一个视图控制器的之后,视图控制器的根视图是 nil:如果根视图为 nil,就会马上调用 loadview 方法去加载一个根视图!如果父类 loadView 方法没有被重写,那么在父类中的 loadView 方法中就会帮我们创建一个根视图;如果重写了父类的 loadView 方法,那么我们在 loadView 方法中就必须创建一个根视图!:loadView 方法执行完毕后紧接着执行 viewDidLoad 方法

当视图控制器的根视图出现时会先后调用 viewWillAppear: animated、viewDidAppear: animated;

当视图控制器的根视图消失时会先后调用 viewWillDisappear: animated、viewDidDisappear: animated

■ 工作原理

// - ViewController.m

  1 #import "ViewController.h"
  2 #import "SecondViewController.h"
  3 @implementation ViewController
  4 
  5 - (void)viewDidLoad {
  6     [super viewDidLoad];
  7     NSLog(@"%s,%d",__FUNCTION__,__LINE__);
  8     
  9     UIButton *nextBT = [UIButton buttonWithType:UIButtonTypeCustom];
 10     nextBT.frame = CGRectMake(40, 80, self.view.frame.size.width - 80, 40);
 11     [nextBT setTitleColor:[UIColor redColor] forState:UIControlStateNormal];
 12     nextBT.backgroundColor = [UIColor cyanColor];
 13     nextBT.layer.masksToBounds = YES;
 14     nextBT.layer.cornerRadius = 4.0;
 15     [nextBT setTitleColor:[UIColor blackColor] forState:UIControlStateHighlighted];
 16     [nextBT setTitle:@"click" forState:UIControlStateNormal];
 17     nextBT.layer.cornerRadius = 8;
 18     [nextBT addTarget:self action:@selector(clickBtn) forControlEvents:UIControlEventTouchUpInside];
 19     [self.view addSubview:nextBT];
 20 
 21 }
 22 
 23 // 进入下级页面
 24 -(void)clickBtn{
 25     SecondViewController *sdVC = [SecondViewController new];
 26     [self.navigationController  pushViewController:sdVC animated:YES];
 27 }
 28 
 29 // 内存警告:
 30 - (void)didReceiveMemoryWarning {
 31     [super didReceiveMemoryWarning];
 32     NSLog(@"%s,%d",__FUNCTION__,__LINE__);
 33     
 34     // 如果当前页面的根视图加载过且根视图并没有呈现
 35     if ([self isViewLoaded] && self.view.window == nil) {
 36         self.view = nil;// 卸载根视图,释放内存
 37     }
 38 }
 39 
 40 // 重写 loadView 方法
 41 -(void)loadView{
 42 
 43     NSLog(@"%s,%d",__FUNCTION__,__LINE__);
 44     // 如果在重写的 loadView 里没有给定根视图,一旦在该方法内使用点语法 self.view,则会无终止地回调 loadView 方法,造成 crash
 45     self.view = [[UIView alloc] initWithFrame:[UIScreen mainScreen].bounds];
 46     self.view.backgroundColor = [UIColor greenColor];
 47 }
 48 
 49 // 视图将要出现
 50 - (void)viewWillAppear:(BOOL)animated{
 51     
 52     [super viewWillAppear:animated];
 53     NSLog(@"%s,%d",__FUNCTION__,__LINE__);
 54 }
 55 
 56 // 视图已经出现
 57 - (void)viewDidAppear:(BOOL)animated{
 58     
 59     [super viewDidAppear:animated];
 60     NSLog(@"%s,%d",__FUNCTION__,__LINE__);
 61 
 62 }
 63 
 64 // 视图将要消失
 65 - (void)viewWillDisappear:(BOOL)animated{
 66     
 67     [super viewWillDisappear:animated];
 68     NSLog(@"%s,%d",__FUNCTION__,__LINE__);
 69 }
 70 
 71 // 视图已经消失
 72 - (void)viewDidDisappear:(BOOL)animated{
 73     
 74     [super viewDidDisappear:animated];
 75     NSLog(@"%s,%d",__FUNCTION__,__LINE__);
 76 }
 77 
 78 // 检测屏幕旋转:需要重写以下几个方法
 79 // 控制手机屏幕是否允许旋转
 80 -(BOOL)shouldAutorotate{
 81     return YES;// 默认 YES
 82 }
 83 
 84 // 设备支持旋转的方向
 85 - (UIInterfaceOrientationMask)supportedInterfaceOrientations{
 86 
 87     return UIInterfaceOrientationMaskAll;
 88 }
 89 
 90 // 屏幕适配:以 iPhone 5 尺寸为例
 91 -(void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator{
 92 
 93     NSLog(@"%s,%d",__FUNCTION__,__LINE__);
 94     UIView * aView = [self.view viewWithTag:100];
 95     if (size.width == 568) {
 96         aView.frame = CGRectMake(0, 0, 568, 220);
 97     }else if (size.width == 320){
 98         aView.frame = CGRectMake(0, 0, 320, 200);
 99     }
100 }
101 
102 
103 // !!-----方法已弃用------!!
104 -(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration{
105     // 暂停音乐、关闭视图交互等
106 
107 }
108 // !!-----方法已弃用-----!!
109 -(void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration{
110 
111     // 添加自定义动画等
112 }
113 // !!-----方法已弃用------!!
114 -(void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation{
115     // 播放音乐、打开视图交互等
116 
117 }
118 
119 @end
注:视图控制器会自动调整 view 的大小以及适应屏幕旋转,当 bounds 一旦被修改,就触发 view 的 layoutSubViews 方法,我们就可以在其中重新布局

// - SecondViewController.m

 1 #import "SecondViewController.h"
 2 @implementation SecondViewController
 3 
 4 - (void)viewDidLoad {
 5     
 6     [super viewDidLoad];
 7     NSLog(@"%s,%d",__FUNCTION__,__LINE__);
 8 }
 9 
10 #pragma mark - overriding_methods
11 
12 // loadView
13 -(void)loadView{
14 
15     NSLog(@"%s,%d",__FUNCTION__,__LINE__);
16     self.view = [[UIView alloc] initWithFrame:[UIScreen mainScreen].bounds];
17     self.view.backgroundColor = [UIColor greenColor];
18 }
19 
20 - (void)viewWillAppear:(BOOL)animated{
21     [super viewWillAppear:animated];
22     NSLog(@"%s,%d",__FUNCTION__,__LINE__);
23 }
24 
25 
26 - (void)viewDidAppear:(BOOL)animated{
27     [super viewDidAppear:animated];
28     NSLog(@"%s,%d",__FUNCTION__,__LINE__);
29 
30 }
31 
32 - (void)viewWillDisappear:(BOOL)animated{
33     [super viewWillDisappear:animated];
34     NSLog(@"%s,%d",__FUNCTION__,__LINE__);
35 }
36 
37 - (void)viewDidDisappear:(BOOL)animated{
38     [super viewDidDisappear:animated];
39     NSLog(@"%s,%d",__FUNCTION__,__LINE__);
40 }
41 
42 @end

日志信息

A. 程序开始运行时

B. 进入 SecondvVewController 时 

C. 返回 viewController 时

注:当我们重写了 loadView 且没有给根视图赋值,那么在 viewDidLoad 调用 self.view 会引起的崩溃,其原因很可能是苹果使用了懒加载

1 - (UIView *)view{
2 
3     if (_view == nil) {
4         [self loadView];
5         [self viewDidLoad];
6     }
7     return _view;
8 }

 

posted on 2018-04-09 11:00  低头捡石頭  阅读(22)  评论(0编辑  收藏  举报

导航