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];
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM