先说结论: 是因为UITabbarController在切换viewController时, 调用了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
的时候, 会调用viewWillAppear
,viewWillDisappear
,viewDidAppear
和viewDidDisappear
. 有时候, 我们的需求是在navigationBar的title位置加一个UISegmentedControl
, 来实现切换viewController
, 并且还要有UIScrollView
的效果. 我们可以在一个大的viewController
里addChildViewController
来实现.但是却不会调用viewWillAppear
之类的方法. 那么UITabbarController
是如何实现的呢?
让我们一步步来探究
1.新建一个项目
2.在storyboard里拖一个UITabbarController
, 并设为entry point
3.创建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是一样的, 只是数字变成1
6.把storyboard
中的2个子viewController
绑定代码
7.在
ViewController2
中的viewWillAppear
方法打断点.
Screen Shot 2016-12-01 at 15.11.04.png
8.查看调用栈
Screen Shot 2016-12-01 at 15.14.33.png
9.我们发现这个在第六个是setSelectedViewController
, 接着调用了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.在自己代码中实现, 2个childViewController切换的时候,只要调用这个方法, 确实会调用viewWillAppear
,viewWillDisappear
,viewDidAppear
和viewDidDisappear
网友评论