UINavigationControllerDelegate 的定义如下,以及两个常用的方法(在IOS7中又新增了几个新的方法)
UIUNavigationController.h
……
@protocol
UINavigationControllerDelegate <
NSObject
>
@optional
// Called when the navigation controller shows a new top view controller via a push, pop or setting of the view controller stack.
- (
void
)navigationController:(
UINavigationController
*)navigationController willShowViewController:(
UIViewController
*)viewController animated:(
BOOL
)animated;
- (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated;
……
当在某个NavigationController或者这个NavigationController的孩子节点下面设置其delegate的时候,这两个方法会进行回调(如果重写了这两个方法,或者其中的一个)
我们把NavigationController以及其孩子节点组成的节点集合成为NavigationController链(真实的结构是一个栈)
当在一条
NavigationController链上的多个节点都设置了delegate。
比如有一条NavigationController链上的节点如下:NavigationController->GrowUpShowViewController(Root)->DetailInfoViewController->TalkingViewController
分别在
GrowUpShowViewController和
TalkingViewController上都设置了delegate
GrowUpShowViewController’s Delegate
viewDidload 方法中写上回调:
self
.
navigationController
.
delegate
=
self
;
回调方法:
#pragma mark - UINavigationControllerDelegate
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated{
if (viewController == self) {
//隐藏父视图的TabBar
RootViewController *tabBarController = (RootViewController *)self.navigationController.tabBarController;
[tabBarController hiddenTabBar];
//加载自定义的TabBar
[self loadCustomTabBarView];
[self initHeaderView];
}else{
RootViewController *tabBarController = (RootViewController *)self.navigationController.tabBarController;
[tabBarController hiddenTabBar];
[self hiddenTabBar];
}
}
TalkingViewController’s Delegate
viewDidload 方法中写上回调:
self
.
navigationController
.
delegate
=
self
;
回调方法:
#pragma mark - UINavigationControllerDelegate
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated{
// 查看WEB内容
if ([viewController isKindOfClass:[NavShowSchoolDesVC class]]) {
RootViewController *tabBarController = (RootViewController *)self.navigationController.tabBarController;
[tabBarController hiddenTabBar];//隐藏主界面的TabBar
}else if(viewController == self && initMessage!=nil) {
RootViewController *tabBarController = (RootViewController *)self.navigationController.tabBarController;
[tabBarController showTabBar];//显示主界面的TabBar
}
}
那么问题随之来了,哪个Controller的方法会收到回调信息,或者是都会收到回调信息
测试发现,在链执行到这里的时候
NavigationController->GrowUpShowViewController(Root)->DetailInfoViewController->
GrowUpShowViewController’s Delegate 的方法会执行
当链执行到这里的时候
TalkingViewController
TalkingViewController’s Delegate 会执行
接着回退到之前的页面
NavigationController->GrowUpShowViewController(Root)->DetailInfoViewController->TalkingViewController
发现只有
TalkingViewController’s Delegate 会执行
得到了结论:使用
self
.
navigationController
.
delegate设置的Delegate是对于当前的NavigationController链是全局的,以当前链上最后一个Controller设置的delegate为准。
解决方法:
在
viewWillAppear方法设置delegate=self,在
viewDidDisappear方法设置delegate=nil
确保不会发生意外的情况。