Reputation: 423
I have set up my class
with UITabBarDelegate
and implemented its method
didSelectItem
to detect when a certain tabBar
item is pressed. Works great. In each tabBar
item I have one containerView
that can show a "you have to login"-page if the user is not logged in, and another containerView
that present viewControllers
that are embedded in a navigationController
.
I would like to keep track of the viewController
that is presented in the current tab
item, and/or the root
viewController
of that tab
.
I have tried a number of different approaches, but most of them return nil or I can't get it to work. I think the whole container
situation makes it harder to handle.
It looks something like this:
@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.
Upvotes: 0
Views: 716
Reputation: 2505
Sorry to have not read your question correctly. Here's what I suggest you do.
All of these view controllers that you're interested in keeping track of: you should have them send a custom notification from within their -viewDidAppear:
(or -viewWillAppear:
) method. Then let your ApolloTabBarController object register for that notification. When it gets the notification, you could then store a reference to the view controller. That reference will always point to the active view controller.
In your individual view controllers, do something like the following:
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
NSNotificationCenter* nc = [NSNotificationCenter defaultCenter];
[nc postNotificationName:@"XYZViewControllerDidBecomeActiveNotification"
object:self];
}
Of course, you would want to use some kind of constant for the notification name.
In your ApolloTabBarController class, register for XYZViewControllerDidBecomeActiveNotification
and implement something like:
- (void)viewControllerDidBecomeActive:(NSNotification *)notification
{
self.activeViewController = [notification object];
}
I hope that helps!
Upvotes: 1
Reputation: 2505
When you're setting up each view controller for each of the tabs, set the tag
property of the UITabBarItem
to correspond to the index of the view controller in the tab bar's viewControllers
array.
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];
Then, you'll be able to grab a reference to view controller.
// In your example, your ApolloTabBarController acts as its own delegate.
- (void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item
{
UIViewController* activeVC =
[[self viewControllers] objectAtIndex:[item tag]];
}
Upvotes: 0