IOS 笔记 - navigationController delegate 劫持

来源:互联网 发布:java heap size 编辑:程序博客网 时间:2024/05/16 23:53
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
确保不会发生意外的情况。
0 0
原创粉丝点击