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
確保不會發生意外的情況。