最近幾天看了好多人的面經,時不時就看到一個問題:
在A頁面跳轉到B頁面的過程中 A 的 viewDidDisappear 方法和 B 的 viewDidAppear 誰先調用?
其實我以前一直理所當然的認為它們的順序就是 A-viewDidDisappear
--> B-viewDidAppear
,至于為什么會這么想,就是感覺
今天寫了個Demo去測試了一下,發現完全不是自己想象的那樣,每一種轉場(Push,Present,TabBar切換)都是不一樣的。
測試
我自定義了兩個類,繼承自UIViewController,為了方便觀察分別叫做A_ViewController
,B_ViewController
,然后重寫了一系列 appear
和 disappear
方法。
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
NSLog(@"A view will appear %@",self);
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
NSLog(@"A view did appear %@",self);
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
NSLog(@"A view will disappear %@",self);
}
- (void)viewDidDisappear:(BOOL)animated {
[super viewDidDisappear: animated];
NSLog(@"A view did disappear %@",self);
}
然后分別用 push, present, 以及 tabbar 的切換來測試,然后查看打印的結果。
Push & Pop
--------------------------PUSH-----------------------------
A view will disappear <A_ViewController: 0x7fa11067a730>
B view will appear <B_ViewController: 0x7fa110516530>
A view did disappear <A_ViewController: 0x7fa11067a730>
B view did appear <B_ViewController: 0x7fa110516530>
--------------------------POP-----------------------------
B view will disappear <B_ViewController: 0x7fa110516530>
A view will appear <A_ViewController: 0x7fa11067a730>
B view did disappear <B_ViewController: 0x7fa110516530>
A view did appear <A_ViewController: 0x7fa11067a730>
在這里的調用順序是和我之前預想的一樣的,也就是
A-willDisappear
--> B-willAppear
--> A-didDisappear
--> B-didAppear
Present & Dismiss
在模態的轉場中就有一些不一樣的事了。我們知道模態轉場有好多種style,其中有兩種我們需要特別注意的UIModalPresentationCustom
,UIModalPresentationOverFullScreen
。我們先看一下除了這兩種style以外的轉場,他們的調用順序是怎樣的。
-----------------------NormalPresent------------------------
A view will disappear <A_ViewController: 0x7fc2a14ac490>
B view will appear <B_ViewController: 0x7fc2a152a880>
B view did appear <B_ViewController: 0x7fc2a152a880>
A view did disappear <A_ViewController: 0x7fc2a14ac490>
-------------------------DISMISS----------------------------
B view will disappear <B_ViewController: 0x7fc2a152a880>
A view will appear <A_ViewController: 0x7fc2a14ac490>
A view did appear <A_ViewController: 0x7fc2a14ac490>
B view did disappear <B_ViewController: 0x7fc2a152a880>
這里其實已經和push的轉場不一樣了。普通模態的轉場的順序是這樣的
A-willDisappear
--> B-willAppear
--> B-didAppear
--> A-didDisappear
再看看前面提到的那兩種特殊的模態轉場。因為在這兩種方式的轉場下A的view是不會消失的,所以所有與A有關的 appear 或 disappear 方法都不會被調用
-----------------------CustomPresent------------------------
B view will appear <B_ViewController: 0x7f960249bac0>
B view did appear <B_ViewController: 0x7f960249bac0>
-------------------------DISMISS----------------------------
B view will disappear <B_ViewController: 0x7f960249bac0>
B view did disappear <B_ViewController: 0x7f960249bac0>
所以在這兩種style下只有B-willAppear
--> B-didAppear
TabBar切換
TabBar 的切換也是一個很神奇的順序
B view will appear <B_ViewController: 0x7f88cbed7160>
A view will disappear <A_ViewController: 0x7f88cbed6680>
A view did disappear <A_ViewController: 0x7f88cbed6680>
B view did appear <B_ViewController: 0x7f88cbed7160>
與push不同的是,TabBar下,會先調用 B 的 willAppear,再調用 A 的 willDisappear
所以TabBar的順序是這樣的:
B-willAppear
--> A-willDisappear
--> A-didDisappear
--> B-didAppear
總結
在每一種轉場下,appear 與 disappear 都有一些不一樣的順序,一定要分清楚,不能一概而論。
Push: A-willDisappear
-->B-willAppear
-->A-didDisappear
-->B-didAppear
Present: A-willDisappear
-->B-willAppear
-->B-didAppear
-->A-didDisappear
CustomPresent: B-willAppear
-->B-didAppear
TabBar: B-willAppear
-->A-willDisappear
-->A-didDisappear
-->B-didAppear
疑惑
為什么要把這個過程弄的這么復雜?目前還沒有想法,如果有知道的朋友,希望告知。