zoukankan      html  css  js  c++  java
  • 3.UIViewController详解

     一. UIViewController,视图控制器,它是UIKit中非常重要的组成部分。它由控制器+View两部分组成。 

         控制器功能:

          -》实现代码逻辑,决定它自带的View的界面显示。

          -》控制器与控制器之间的通信,如传值,跳转。

          -》以及与Model和View间的信息传递。

          -》可以通过addChirldViewController来添加子控制器。(如抽屉效果,多选tableView都是采用此方式)

         视图功能:

          -》向用户展示信息

          -》可以添加子视图,设置子视图的层别

          -》可以接收响应事件(用户在触摸后屏幕后就会形成一个基于触摸点的UIEvent事件)

           这个事件通过 application - > keyWindow- > UIViewController(可选择,如果没有则直接传递给下一级)-》View-》subView -》.....->知道最终找到触摸点所在的那个位置对应的视图->查找该处视图是否有添加响应时间-》没有则自动释放-》有则通过该触摸点View->父视图-》控制器(没有直接向上一级出传递)-》keyWindow-》applcation。

    二. UIViewController的生命周期

        经过测试执行顺序由上到下:

        1. 首先给视图控制器分配空间,然后初试化,接着创建唯一的UIView视图。

         2016-03-10 22:24:47.029 Demo_10_抽屉效果[74967:4603110] +[MainViewController alloc],分配空间

        2. init方法初始化,将这块内存的数据清空;系统也提供了init的改写方法,在初试化的时候直接连View一起加载好,

           视图控制器初试化好之后就是加载VIew,加载View有三种方式.

          -> 通过initWithCoder:从故事版中加载

          -> 通过initWithNibName:从xib中加载

          -> 通过自己使用代码进行创建。

           在没有故事版和storyBoard调用次方法视图可以从Xib  StroyBoard 代码中创建

       2016-03-10 22:24:47.029 Demo_10_抽屉效果[74967:4603110] -[MainViewController initWithCoder:],从故事板归档文件中加载视图出来了 

       - (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil 从xib二进制文件中加载出来了

          将解压或者代码创建视图加载出来

       3. loadView,将从storyBoard或者Nib文件,或者代码创建的View加载到系统中

      2016-03-10 22:24:47.061 Demo_10_抽屉效果[74967:4603110] -[MainViewController loadView],加载控制器的唯一视图View视图已经加载出来了

       4. View已经加载出来了,如果改视图控制器不销毁,只是界面切换,那么此方法只会执行一次。

     2016-03-10 22:24:47.062 Demo_10_抽屉效果[74967:4603110] -[MainViewController viewDidLoad],视图已经加载出来了  视图将要显示在手机屏幕上

       5. View将要显示到屏幕上,通常我们需要进行一些预先加载的操作可以写到这里,比如添加通知事件。

     2016-03-10 22:24:47.063 Demo_10_抽屉效果[74967:4603110] -[MainViewController viewWillAppear:],视图将要显示在屏幕界面上了

       6. 因为ViewFrame已经计算好了,且将要显示到屏幕上,但是它的子视图还没有固定好,所有先要调用子视图的两个方法

            视图开始布局子视图了,当子视图的约束写在此方法中时,当视图变化时候,子视图会跟着变化。

      2016-03-10 22:24:47.069 Demo_10_抽屉效果[74967:4603110] -[MainViewController viewWillLayoutSubviews],视图开始布局自视图了

        . 2016-03-10 22:24:47.069 Demo_10_抽屉效果[74967:4603110] -[MainViewController viewDidLayoutSubviews],视图的子视图已经布局完了

       7.  subView布局好之后,View才开始真正的显示视图

           [MainViewController viewDidAppear:],视图已经出现在屏幕上了

       8.  View将要消失

          -(void)viewWillDisappear:(BOOL)animated

       9. View已经消失在界面上了。通常我们一些通知事件移除可以写在此方法中。

          - (void)viewDidDisappear:(BOOL)animated

       10.控制器收到了内存不足警告

          - (void)didReceiveMemoryWarning

       11.下面两个是死亡方法

          - (void)viewDidUnLoad 视图警告内存不足可能被卸掉,下次就会继续执行viewDidLoad

          - (void)dealloc 当前视图控制器销毁

    三 . UIViewController中布局子视图的时机。

         通常我们所说的布局子视图其实就是调用layOutSubViews.应为只有这个方法才会对父视图上的所有子视图进行统一的计算,然后再进行调用。

         下面请看这几个方法:

          1. layOutSubViews: 这个方法默认是什么都不做的,我们需要布局的子视图对象的frame计算方式都可以写在这里。

          2. setNeedsLayout方法:将调用者标记为需要进行重新布局,采取异步调用layoutIfNeed刷行布局(异步及另外开辟线程,不会立即刷新)。同时会调用layOutSubViews的方式刷新子视图布局。 

          3.layoutIfNeeded方法:如果该对象有需要刷新的标记,则会立即自动调用layoutSubViews。(如果没有这个标记的话,则不会马上调用layOutSubViews);视图在第一次看时的时候都会有需要刷新的标记,所以可以调用  [xxx.view layOutIfNeeded]

          4. 子视图重绘改变布局:

              -drawRect:(CGRect)rect方法:重写此方法执行重绘任务。

              -setNeedsDisplay方法,标记为需要绘,异步执行上面的方法进行绘制。例如当我们在做画笔工具的时候需要对路径进行实时勾勒,可以调用此方法。

               -setNessdsDisplayInRect:(CGRect)invalidRect方法:标记为需要局部重绘。

    #pragma mark NSObject 线程安全与运行环境加载
    + (void)load {
        NSLog(@"%s",__func__);
    }
    
    + (void)initialize {
            NSLog(@"%s",__func__);
    }
    
    + (instancetype)alloc {
            NSLog(@"%s,分配空间",__func__);
        return  [super alloc];
    }
    
    //+ (instancetype)allocWithZone:(struct _NSZone *)zone {
    //        NSLog(@"%s,分配空间",__func__);
    //    return  [self allocWithZone:zone];
    //}
    
    - (instancetype)init {
        NSLog(@"%s,初始化空间",__func__);
        return  [self init];
    }
    
    //- (instancetype)initWithCoder:(NSCoder *)aDecoder {
    //     NSLog(@"%s,从归档文件总加载",__func__);
    //    return [super initWithCoder: aDecoder];
    //}
    
    - (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
         NSLog(@"%s,从Nib二进制文件中加载",__func__);
        return [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    }
    
    
    - (void)loadView {
        NSLog(@"%s,加载控制器的唯一视图View",__func__);
        [super loadView];
    }
    
    - (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator {
         NSLog(@"%s,视图的size发生改变",__func__);
        [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
    }
    
    - (void)viewDidLoad {
        NSLog(@"%s,视图已经加载出来了",__func__);
        [super viewDidLoad];
    }
    
    - (void)viewWillAppear:(BOOL)animated {
            NSLog(@"%s,视图将要显示在屏幕界面上了",__func__);
        [super viewWillAppear:animated];
    }
    
    //- (void)viewWillLayoutSubviews {
    //        NSLog(@"%s,视图开始布局自视图了",__func__);
    //    [super viewWillLayoutSubviews];
    //    UIButton* button = [[UIButton alloc]initWithFrame:CGRectMake(20, 20, 100, 30)];
    //    [button setTitle:@"test btn" forState:UIControlStateNormal];
    //    [button setTintColor:[UIColor greenColor]];
    //    [self.view addSubview:button];
    //}
    //
    //- (void)viewDidLayoutSubviews {
    //        NSLog(@"%s,视图的子视图已经布局完了",__func__);
    //    [super viewDidLayoutSubviews];
    //}
    
    - (void)viewDidAppear:(BOOL)animated {
            NSLog(@"%s,视图已经出现在屏幕上了",__func__);
        [super viewDidAppear:animated];
    }
    
    - (void)viewWillDisappear:(BOOL)animated {
            NSLog(@"%s,视图将要消失了",__func__);
        [super viewWillDisappear:animated];
    }
    
    - (void)viewDidDisappear:(BOOL)animated {
            NSLog(@"%s,视图已经消失了",__func__);
        [super viewDidDisappear:animated];
    }
    
    
    #pragma mark 可选择性的
    - (void)loadViewIfNeeded {
        [super loadViewIfNeeded];
    }
  • 相关阅读:
    Mybatis数据库操作的返回值
    Java中设置classpath、path、JAVA_HOME的作用?
    mysql备份与还原,增量备份;使用ibd和frm文件恢复数据
    SQLAlchemy会话与事务控制:互斥锁和共享锁
    log4j设置,以及中文乱码,通过过滤器输出指定级别的日志,或者指定级别范围的日志
    SQL重复记录查询-count与group by having结合查询重复记录
    css样式美化 下拉框 select 样式
    人人都是 DBA(XIII)索引信息收集脚本汇编
    java线程安全问题之静态变量、实例变量、局部变量
    java uuid第一次性能
  • 原文地址:https://www.cnblogs.com/wwoo/p/5264027.html
Copyright © 2011-2022 走看看