如何检查当前 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.
当您为每个选项卡设置每个视图控制器时,将 UITabBarItem
的 tag
属性 设置为对应于视图控制器中的索引标签栏的 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];
}
希望对您有所帮助!
我已经用 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.
当您为每个选项卡设置每个视图控制器时,将 UITabBarItem
的 tag
属性 设置为对应于视图控制器中的索引标签栏的 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];
}
希望对您有所帮助!