IOS 笔记 - navigationController delegate 劫持

本文详细介绍了UINavigationControllerDelegate的使用方式及其实现细节,探讨了如何通过设置代理来控制导航控制器的行为,并提供了具体示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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
确保不会发生意外的情况。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值