如何检查当前 viewController 或根 viewController?

How do I check present viewController or root viewController?

我已经用 UITabBarDelegate 设置了我的 class 并实现了它的 method didSelectItem 来检测何时按下某个 tabBar 项目。效果很好。在每个 tabBar 项目中,我有一个 containerView 如果用户未登录可以显示 "you have to login" 页面,另一个 containerView 显示 viewControllers嵌入在 navigationController 中。

我想跟踪当前 tab 项目中显示的 viewController,and/or root viewController tab

我尝试了多种不同的方法,但大多数方法 return 都没有,或者我无法让它发挥作用。我认为整个 container 情况让它更难处理。

看起来像这样:

@interface MyTabBarController () <UITabBarDelegate> 

- (void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item {

    NSUInteger indexOfTab = [[tabBar items] indexOfObject:item];

    switch (indexOfTab) {
        case 0: {
            NSLog(@"PRESSIIING %lu", (unsigned long)[[tabBar items] indexOfObject:item]);
            break;
        }
        case 1: {
           NSLog(@"PRESSIIING %lu", (unsigned long)[[tabBar items] indexOfObject:item]);
           break;
        }
        case 2: {
           NSLog(@"PRESSIIING %lu", (unsigned long)[[tabBar items] indexOfObject:item]);

//These return nil
            NSLog(@"AAAAAA %@", ((UINavigationController*)_appD.window.rootViewController).visibleViewController);
            NSLog(@"AAAAAA %@", ((UITabBarController*)_appD.window.rootViewController).selectedViewController);
            NSLog(@"AAAAAA %@", self.navigationController.topViewController);
            NSLog(@"AAAAAA %@", self.navigationController.visibleViewController);

//This returns with a value, but can't get it to work with conditionals, that is, when I'm in root, the else is triggered
            NSLog(@"AAAAAA %@", self.tabBar.window.rootViewController);

            if(!self.tabBar.window.rootViewController) {
                NSLog(@"THIS IS NOT ROOT");

            }else {
                NSLog(@"this is ROOT");
            }

// This returns nil
            ((UINavigationController*)_appD.window.rootViewController).visibleViewController;
            ((UITabBarController*)_appD.window.rootViewController).selectedViewController;

            //Doesn't work
            if([self.navigationController.viewControllers[0] isKindOfClass:[ExperiencesListViewController class]]) {
                           NSLog(@"IS KIND OF CLASS LIST");
                       }
                       if([self.navigationController.viewControllers[0].childViewControllers isKindOfClass:[ExperiencesContainerViewController class]]) {
                           NSLog(@"IS KIND OF CLASS CONTAINER");
                     }
           break;
       }
        case 3: {
           NSLog(@"PRESSIIING %lu", (unsigned long)[[tabBar items] indexOfObject:item]);
           break;
       }
        case 4: {
           NSLog(@"PRESSIIING %lu", (unsigned long)[[tabBar items] indexOfObject:item]);
           break;
       }
        default:
            break;
    }
}

So, what else can I try? Seems like I have to use `self.tabBar.window.rootViewController` in some way, no?

***EDIT*** 
Oh, and I have tried the `tabBarController` delegate but that doesn't trigger. Also, the `tabBar` is constructed programmatically if that helps.

当您为每个选项卡设置每个视图控制器时,将 UITabBarItemtag 属性 设置为对应于视图控制器中的索引标签栏的 viewControllers 数组。

UIViewController* myFirstVC = [[UIViewController alloc] init];
UIViewController* mySecondVC = [[UIViewController alloc] init];

// "self" is your ApolloTabBarController.
[self setViewControllers:@[myFirstVC, mySecondVC]];

myFirstVC.tabBarItem = 
    [[UITabBarItem alloc] initWithTitle:@"First" image:nil tag:0];

mySecondVC.tabBarItem = 
    [[UITabBarItem alloc] initWithTitle:@"Second" image:nil tag:1];

然后,您将能够获取对视图控制器的引用。

// In your example, your ApolloTabBarController acts as its own delegate.
- (void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item
{
    UIViewController* activeVC = 
        [[self viewControllers] objectAtIndex:[item tag]];
}

很抱歉没有正确阅读您的问题。这是我建议你做的。

您有兴趣跟踪的所有这些视图控制器:您应该让它们从它们的 -viewDidAppear:(或 -viewWillAppear:)方法中发送自定义通知。然后让您的 ApolloTabBarController 对象注册该通知。当它收到通知时,您可以存储对视图控制器的引用。该引用将始终指向活动视图控制器。

在您的个人视图控制器中,执行如下操作:

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
    NSNotificationCenter* nc = [NSNotificationCenter defaultCenter];

    [nc postNotificationName:@"XYZViewControllerDidBecomeActiveNotification"
                      object:self];
}

当然,您可能希望为通知名称使用某种常量。

在您的 ApolloTabBarController class 中,注册 XYZViewControllerDidBecomeActiveNotification 并实现如下内容:

- (void)viewControllerDidBecomeActive:(NSNotification *)notification
{
    self.activeViewController = [notification object];
}

希望对您有所帮助!