先說結(jié)論: 是因為UITabbarController在切換viewController時, 調(diào)用了transitionFromViewController方法
/*
This method can be used to transition between sibling child view controllers. The receiver of this method is
their common parent view controller. (Use [UIViewController addChildViewController:] to create the
parent/child relationship.) This method will add the toViewController's view to the superview of the
fromViewController's view and the fromViewController's view will be removed from its superview after the
transition completes. It is important to allow this method to add and remove the views. The arguments to
this method are the same as those defined by UIView's block animation API. This method will fail with an
NSInvalidArgumentException if the parent view controllers are not the same as the receiver, or if the
receiver explicitly forwards its appearance and rotation callbacks to its children. Finally, the receiver
should not be a subclass of an iOS container view controller. Note also that it is possible to use the
UIView APIs directly. If they are used it is important to ensure that the toViewController's view is added
to the visible view hierarchy while the fromViewController's view is removed.
*/
- (void)transitionFromViewController:(UIViewController *)fromViewController toViewController:(UIViewController *)toViewController duration:(NSTimeInterval)duration options:(UIViewAnimationOptions)options animations:(void (^ __nullable)(void))animations completion:(void (^ __nullable)(BOOL finished))completion NS_AVAILABLE_IOS(5_0);
UITabbarController
每次切換viewController
的時候, 會調(diào)用viewWillAppear
,viewWillDisappear
,viewDidAppear
和viewDidDisappear
. 有時候, 我們的需求是在navigationBar的title位置加一個UISegmentedControl
, 來實現(xiàn)切換viewController
, 并且還要有UIScrollView
的效果. 我們可以在一個大的viewController
里addChildViewController
來實現(xiàn).但是卻不會調(diào)用viewWillAppear
之類的方法. 那么UITabbarController
是如何實現(xiàn)的呢?
讓我們一步步來探究
1.新建一個項目
2.在storyboard里拖一個UITabbarController
, 并設(shè)為entry point
3.創(chuàng)建ViewController1
和ViewController2
4.ViewController1
的代碼
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(@"1viewDidLoad");
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
NSLog(@"1viewWillAppear");
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
NSLog(@"1viewDidAppear");
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
NSLog(@"1viewWillDisappear");
}
- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
NSLog(@"1viewDidDisappear");
}
5.ViewController2
的代碼和1是一樣的, 只是數(shù)字變成1
6.把storyboard
中的2個子viewController
綁定代碼
7.在
ViewController2
中的viewWillAppear
方法打斷點.
8.查看調(diào)用棧
9.我們發(fā)現(xiàn)這個在第六個是setSelectedViewController
, 接著調(diào)用了transitionFromViewController:toViewController
, 這是什么方法, 沒聽說過?
10.UITabBarController *v = nil; [v transitionFromViewController:nil toViewController:nil duration:0 options:0 animations:nil completion:nil];
手動試一下這個方法看看是否公開
11.command點擊進入這個方法
/*
This method can be used to transition between sibling child view controllers. The receiver of this method is
their common parent view controller. (Use [UIViewController addChildViewController:] to create the
parent/child relationship.) This method will add the toViewController's view to the superview of the
fromViewController's view and the fromViewController's view will be removed from its superview after the
transition completes. It is important to allow this method to add and remove the views. The arguments to
this method are the same as those defined by UIView's block animation API. This method will fail with an
NSInvalidArgumentException if the parent view controllers are not the same as the receiver, or if the
receiver explicitly forwards its appearance and rotation callbacks to its children. Finally, the receiver
should not be a subclass of an iOS container view controller. Note also that it is possible to use the
UIView APIs directly. If they are used it is important to ensure that the toViewController's view is added
to the visible view hierarchy while the fromViewController's view is removed.
*/
- (void)transitionFromViewController:(UIViewController *)fromViewController toViewController:(UIViewController *)toViewController duration:(NSTimeInterval)duration options:(UIViewAnimationOptions)options animations:(void (^ __nullable)(void))animations completion:(void (^ __nullable)(BOOL finished))completion NS_AVAILABLE_IOS(5_0);
12.在自己代碼中實現(xiàn), 2個childViewController切換的時候,只要調(diào)用這個方法, 確實會調(diào)用viewWillAppear
,viewWillDisappear
,viewDidAppear
和viewDidDisappear