Как проверить текущий viewController или root viewController? - PullRequest
0 голосов
/ 13 февраля 2020

Я настроил class с помощью UITabBarDelegate и внедрил его method didSelectItem, чтобы определять, когда нажимается определенный элемент tabBar. Работает отлично. В каждом элементе tabBar есть одна containerView, на которой может отображаться страница «Вы должны войти в систему», если пользователь не вошел в систему, и другая containerView, представляющая viewControllers, встроенная в navigationController ,

Я бы хотел отслеживать viewController, представленный в текущем элементе tab, и / или root viewController этого tab.

Я пробовал несколько разных подходов, но большинство из них возвращает ноль, или я не могу заставить его работать. Я думаю, что вся ситуация 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.

Ответы [ 2 ]

1 голос
/ 19 февраля 2020

Извините, что неправильно прочитал ваш вопрос. Вот что я предлагаю вам сделать.

Все эти контроллеры представлений, которые вы хотите отслеживать: вам нужно, чтобы они отправляли пользовательское уведомление изнутри их метода -viewDidAppear: (или -viewWillAppear:). Затем позвольте вашему объекту ApolloTabBarController зарегистрироваться для этого уведомления. Когда он получает уведомление, вы можете сохранить ссылку на контроллер представления. Эта ссылка всегда будет указывать на активный контроллер представления.

В ваших отдельных контроллерах представления сделайте что-то вроде следующего:

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

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

Конечно, вы захотите использовать какую-то константу для имени уведомления.

В вашем классе ApolloTabBarController зарегистрируйтесь для XYZViewControllerDidBecomeActiveNotification и реализуйте что-то вроде:

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

Надеюсь, это поможет!

0 голосов
/ 19 февраля 2020

Когда вы настраиваете каждый контроллер представления для каждой из вкладок, установите свойство tag для UITabBarItem, чтобы оно соответствовало индексу контроллера представления в массиве 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]];
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...