【iOS】ViewController life cycle


Preface

UIViewController plays a very important role in iOS development. It is the bridge between the view and the data model. Data is displayed on the view in an orderly manner through the management of UIViewController. As the most basic class in UIKit, generally complex projects cannot do without UIViewController as the base class. So it is necessary to understand the entire life cycle of UIViewController.


1. UIViewController life cycle related functions

The following is the calling function of the UIViewController life cycle method:

  • init(coder:) or init(nibName:bundle:) (may not be called both at the same time depending on how the view is loaded)

The init method is similar to the initCoder method, but the environment in which the knowledge is called is different. If initialized with code, the init method will be called. If initialized from a nib file or archive (xib, storyboard), initCoder will be called. initCoder is a method in the NSCoding protocol. NSCoding is the protocol responsible for encoding, decoding, and archiving processing.

  • loadView (): ViewController calls this method when the View needs to be displayed but it is nil.
    If the code maintains View, you need to rewrite this method. If you use xib to maintain View, you do not need to rewrite it.
  • viewDidLoad (): Our most commonly used method, we will put the initialization of class member objects and variables in this method. Regardless of whether the view appears or disappears after the class is created, this method will only be called once in the layout.
  • viewWillAppear() : Called when the view is about to be displayed.
  • viewDidAppear (): The method is that the view has appeared.
  • viewWillLayoutSubviews(), viewDidLayoutSubviews() : These methods are used to handle changes in view layout, usually performing layout-related operations here. viewWillLayoutSubviews() is called before the subviews are re-layout, and viewDidLayoutSubviews() is called after the sub-views are re-layout.
  • viewWillDisappear (): The method is that the view is about to disappear. -viewDidDisappear(): The view has disappeared.
  • traitCollectionDidChange () (if the view controller's trait collection changes)
  • didReceiveMemoryWarning () (if the system is low on memory)

2. Execution sequence

Let's use a program example to see our execution sequence: we create two viewcontrollers AB, and then set a button to switch between them.

#import "AViewController.h"
#import "BViewController.h"
@interface AViewController ()

@end

@implementation AViewController

- (void)viewDidLoad {
    
    
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor redColor];
    _btn1 = [UIButton buttonWithType:UIButtonTypeSystem];
    [_btn1 setTitle:@"next_push" forState:UIControlStateNormal];
    _btn1.frame = CGRectMake(self.view.frame.size.width / 2 - 50, self.view.frame.size.height / 2 - 50, 200, 100);
    [self.view addSubview:_btn1];
    [_btn1 addTarget:self action:@selector(next_present) forControlEvents:UIControlEventTouchUpInside];
        NSLog(@"%s", __func__);

}

- (void)next_present {
    
    
    BViewController *B = [[BViewController alloc] init];
    NSLog(@"---------A->B---------");
    B.modalPresentationStyle = UIModalPresentationFullScreen;
    [self presentViewController:B animated:YES completion:nil];
}

- (void)loadView {
    
    
    [super loadView];
    NSLog(@"%s", __func__);
}

- (void)viewWillAppear:(BOOL)animated {
    
    
    NSLog(@"%s", __func__);

}

- (void)viewWillLayoutSubviews {
    
    
    NSLog(@"%s", __func__);

}

- (void)viewDidLayoutSubviews {
    
    
    NSLog(@"%s", __func__);

}

- (void)viewDidAppear:(BOOL)animated {
    
    
    NSLog(@"%s", __func__);

}

- (void)viewWillDisappear:(BOOL)animated {
    
    
    NSLog(@"%s", __func__);

}

- (void)viewDidDisappear:(BOOL)animated {
    
    
    NSLog(@"%s", __func__);

}
@end
#import "BViewController.h"

@interface BViewController ()

@end

@implementation BViewController

- (void)viewDidLoad {
    
    
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor greenColor];
    _btn1 = [UIButton buttonWithType:UIButtonTypeSystem];
    [_btn1 setTitle:@"present" forState:UIControlStateNormal];
    _btn1.frame = CGRectMake(self.view.frame.size.width / 2 - 50, self.view.frame.size.height / 2 - 50, 200, 100);
    [self.view addSubview:_btn1];
    [_btn1 addTarget:self action:@selector(next_present) forControlEvents:UIControlEventTouchUpInside];
        NSLog(@"%s", __func__);

}

- (void)next_present {
    
    
    NSLog(@"---------B->A---------");
    [self dismissViewControllerAnimated:YES completion:nil];
    
}

- (void)loadView {
    
    
    [super loadView];
    NSLog(@"%s", __func__);
}

- (void)viewWillAppear:(BOOL)animated {
    
    
    NSLog(@"%s", __func__);

}

- (void)viewWillLayoutSubviews {
    
    
    NSLog(@"%s", __func__);

}

- (void)viewDidLayoutSubviews {
    
    
    NSLog(@"%s", __func__);

}

- (void)viewDidAppear:(BOOL)animated {
    
    
    NSLog(@"%s", __func__);

}

- (void)viewWillDisappear:(BOOL)animated {
    
    
    NSLog(@"%s", __func__);

}

- (void)viewDidDisappear:(BOOL)animated {
    
    
    NSLog(@"%s", __func__);

}
@end

Insert image description here
Output result:

2023-09-15 09:24:00.429478+0800 viewcontroller[13601:419399] -[AViewController loadView]
2023-09-15 09:24:00.432183+0800 viewcontroller[13601:419399] -[AViewController viewDidLoad]
2023-09-15 09:24:00.436078+0800 viewcontroller[13601:419399] -[AViewController viewWillAppear:]
2023-09-15 09:24:00.438626+0800 viewcontroller[13601:419399] -[AViewController viewWillLayoutSubviews]
2023-09-15 09:24:00.438685+0800 viewcontroller[13601:419399] -[AViewController viewDidLayoutSubviews]
2023-09-15 09:24:00.459615+0800 viewcontroller[13601:419399] -[AViewController viewDidAppear:]
2023-09-15 09:24:01.630610+0800 viewcontroller[13601:419399] ---------A->B---------
2023-09-15 09:24:01.631055+0800 viewcontroller[13601:419399] -[BViewController loadView]
2023-09-15 09:24:01.631497+0800 viewcontroller[13601:419399] -[BViewController viewDidLoad]
2023-09-15 09:24:01.635034+0800 viewcontroller[13601:419399] -[AViewController viewWillDisappear:]
2023-09-15 09:24:01.635241+0800 viewcontroller[13601:419399] -[BViewController viewWillAppear:]
2023-09-15 09:24:01.637124+0800 viewcontroller[13601:419399] -[BViewController viewWillLayoutSubviews]
2023-09-15 09:24:01.637377+0800 viewcontroller[13601:419399] -[BViewController viewDidLayoutSubviews]
2023-09-15 09:24:02.142068+0800 viewcontroller[13601:419399] -[BViewController viewDidAppear:]
2023-09-15 09:24:02.142392+0800 viewcontroller[13601:419399] -[AViewController viewDidDisappear:]
2023-09-15 09:24:02.397591+0800 viewcontroller[13601:419399] ---------B->A---------
2023-09-15 09:24:02.400464+0800 viewcontroller[13601:419399] -[BViewController viewWillDisappear:]
2023-09-15 09:24:02.400764+0800 viewcontroller[13601:419399] -[AViewController viewWillAppear:]
2023-09-15 09:24:02.906699+0800 viewcontroller[13601:419399] -[AViewController viewDidAppear:]
2023-09-15 09:24:02.906936+0800 viewcontroller[13601:419399] -[BViewController viewDidDisappear:]
2023-09-15 09:24:03.331584+0800 viewcontroller[13601:419399] ---------A->B---------
2023-09-15 09:24:03.332027+0800 viewcontroller[13601:419399] -[BViewController loadView]
2023-09-15 09:24:03.332457+0800 viewcontroller[13601:419399] -[BViewController viewDidLoad]
2023-09-15 09:24:03.335091+0800 viewcontroller[13601:419399] -[AViewController viewWillDisappear:]
2023-09-15 09:24:03.335375+0800 viewcontroller[13601:419399] -[BViewController viewWillAppear:]
2023-09-15 09:24:03.336893+0800 viewcontroller[13601:419399] -[BViewController viewWillLayoutSubviews]
2023-09-15 09:24:03.337049+0800 viewcontroller[13601:419399] -[BViewController viewDidLayoutSubviews]
2023-09-15 09:24:03.841095+0800 viewcontroller[13601:419399] -[BViewController viewDidAppear:]
2023-09-15 09:24:03.841359+0800 viewcontroller[13601:419399] -[AViewController viewDidDisappear:]
2023-09-15 09:24:04.031338+0800 viewcontroller[13601:419399] ---------B->A---------
2023-09-15 09:24:04.033750+0800 viewcontroller[13601:419399] -[BViewController viewWillDisappear:]
2023-09-15 09:24:04.033976+0800 viewcontroller[13601:419399] -[AViewController viewWillAppear:]
2023-09-15 09:24:04.537921+0800 viewcontroller[13601:419399] -[AViewController viewDidAppear:]
2023-09-15 09:24:04.538108+0800 viewcontroller[13601:419399] -[BViewController viewDidDisappear:]

From this we can derive the life cycle execution sequence of our ViewController:

  • When popping up only a single view controller
loadView->didloadView->willAppear->willLayoutsubviews->didLayoutSubviews->didAppear
  • When two view controllers switch back and forth, our first view controller will not call the disAppear function directly, but will call the disAppear function after the second view controller didAppaer, and vice versa.

important point

loadview:

Every time the view of UIViewController is accessed (such as vc.view, self.view) and the view is nil, the loadView method will be called. This is why we must add it when we override the loadview method [super loadView];, because calling this method can automatically generate our view. If we cannot find the view, our program will always call the loadview method to find our view.

Guess you like

Origin blog.csdn.net/weixin_72437555/article/details/132889032
Recommended