UIMoreNavigationController 和 UITabBarController 的问题
Posted
技术标签:
【中文标题】UIMoreNavigationController 和 UITabBarController 的问题【英文标题】:Issues with UIMoreNavigationController and UITabBarController 【发布时间】:2012-02-24 12:02:56 【问题描述】:这个问题困扰了我一段时间,但我想我终于弄清楚了哪里出了问题;我认为我现在只需要一个解决方案......
这是应用的背景。用户可以使用大约 6 个不同的选项卡,使用 UITabBarController 显示。这些选项卡中的每一个都是一个自定义 UIViewController 子类,位于 UINavigationController 内。所有 6 个选项卡都设置在一个 nib 文件 (MainWindows.xib) 中。
我需要能够隐藏和显示不同的选项卡,具体取决于用户是否登录以及他们登录的对象。我有这样的工作:
在应用程序启动时(应用程序:didFinishLaunching: ...),六个选项卡存储到我拥有的 NSMutableArray 中。这工作正常...
当用户登录或注销时,我从 NSMutableArray 访问他可以使用的选项卡,并将它们添加到 UITabBarController 中,如下所示:
[tabBar setViewControllers: [NSArray arrayWithObjects:
[viewControllers objectAtIndex:1],
[viewControllers objectAtIndex:5],
nil] animated:YES];
viewControllers 是我之前用 6 个选项卡制作的 NSMutableArray。在我创建它之后对其执行 NSLog 会给出这个结果,这是我所期望的:
2012-02-24 11:45:57.690 [redacted][26155:207] (
"<UINavigationController: 0x8249db0>",
"<UINavigationController: 0x841a3f0>",
"<UINavigationController: 0x824be40>",
"<UINavigationController: 0x824dbd0>",
"<UINavigationController: 0x824e810>",
"<UINavigationController: 0x841dfb0>"
)
但是,当我从最后一个自定义视图控制器(位于该列表中的最后一个导航控制器内)打印 self.parentViewController 的值时,我得到以下信息:
2012-02-24 11:54:51.247 [REDACTED][26306:207] <UIMoreNavigationController: 0x826ab00>
2012-02-24 11:54:51.248 [REDACTED][26306:207] <UITabBarController: 0x8257c50>
第一行是self.parentViewController,第二行是self.parentViewController.parentViewController
这似乎表明heirachy是:
UITabBarController -> UIMoreNavigationController -> MyCustomController
但是当我打印 [self.parentViewController.parentViewController viewControllers]
我仍然得到:
(
"<UINavigationController: 0x8259770>",
"<UINavigationController: 0x825aa60>",
"<UINavigationController: 0x825bec0>",
"<UINavigationController: 0x82612c0>",
"<UINavigationController: 0x8261ec0>",
"<UINavigationController: 0x8263b00>"
)
UIMoreNavigationController 去哪儿了?谁能解释发生了什么?我遇到了与此相关的问题,因为我使用了该数组,但是最后一个 UINavigationController 不是它声称的对象。
我有一种预感,苹果正在摆弄幕后的对象,以使程序员更容易......
我将尝试回答您对代码结构、我如何使用不同对象或测试某些代码的任何问题。非常感谢您。
【问题讨论】:
首先,如果self.parentViewController.parentViewController
是标签栏控制器,您为什么希望该数组发生变化?
其次,你的 UIMoreNavigationController 是在哪里创建的?如果它是在您的最后一个自定义视图控制器中创建的,那么标签栏控制器将对此一无所知。 tabbarcontroller 中的视图控制器数组没有定义视图控制器层次结构。在其中一个自定义视图中更改该层次结构也不会影响该视图控制器数组。
这不是我的 UIMoreNavigationController。这就是问题所在,它不是我创造的。我大约 100% 确定我的项目中没有名为 UIMoreNavigationController 的类...我将尝试上传一个最小的项目,稍后仍会显示该类。
我觉得很奇怪你的日志有一个UIMoreNavigationController
类的证据 - AFAIK 甚至 ios 都没有这样的类。但也许我只是过时了......你使用哪个版本的 iOS SDK?
我不知道您是否设法解决了这个问题(即使您已经接受了答案),但我遇到了完全相同的问题并设法将其追踪到 UITabBarController 的创建方式。而不是使用[[UITabBarController alloc] initWithCoder:nil]
,而是使用[[UITabBarController alloc] init]
。这可能看起来很明显,但我只是浪费了 2 个小时试图解决这个问题!
【参考方案1】:
其实Tabbar的moreViewController是UIMoreNavigationController
。 (大家可以看看private header on GitHub)
如文档所述,viewController 属性仅包含您已添加到标签栏的 viewController:You must also not look for the More navigation controller in the array of view controllers stored in the viewControllers property. The tab bar controller does not include the More navigation controller in that array of objects.
在此处查看文档:UITabbarViewController。
反正我不明白,你的问题到底是什么。如果您需要访问UIMoreNavigationController
,请通过UITabBarViewController
的moreNavigationController
属性进行。
但 'viewControllers' 属性始终只包含您已添加到 TabBar 的那些 ViewController。
【讨论】:
抱歉我很挑剔,但我坚持认为没有UIMoreNavigationController
类这样的东西。我不知道您在引用的文档中的何处看到此类名称 - 名为 moreNavigationController
的属性已明确记录为类 UINavigationController
的实例。在所有其他方面:很好的答案!
它没有记录为那个类。但是,如果您查看调试器,您将始终看到该类名。显然它必须是 UINavigationController 的一个子类,因为属性是按照它定义的。如果你想看看标题,看这里:github.com/kennytm/iphone-private-frameworks/blob/master/UIKit/…
查看UITabBarController的头部,可以清楚的看到:UINavigationController *_moreNavigationController;
- 没有UIMoreNavigationController
这样的类。 UIKit 框架也不包含此类。
jaydee3 是正确的。当您不知道自己在说什么时,您不应该发表评论。如果你使用控制台打印出标签栏控制器的moreNavigationController,你会看到这个。 (lldb) po [tbc moreNavigationController] (UINavigationController *) $1 = 0x0fa51400 由于您没有说出您的实际问题是什么,因此我对此无话可说。但我很确定没有UIMoreNavigationController
这样的类。 “更多”导航控制器只是一个由UITabBarController
管理的UINavigationController
,用于保存任何多余的子控制器。参见 Apple 的UITabBarController reference,但您也可以仔细检查 UIKit 框架头文件UITabBarController.h
。
相应地,我无法重现您显示<UIMoreNavigationController: 0x826ab00>
的调试输出。在我的环境(SDK 5.0)中,我只得到<UINavigationController: 0x12345678>
,无论我是检查自定义视图控制器的父级还是标签栏控制器的子级。
【讨论】:
当您运行该测试并且无法重现时,是不是第 5 个标签栏项目(如果您明白我的意思,那么它在more
显示中,而不是默认 4 个标签)?我认为它只出现在那里...似乎是一个奇怪的错误,我可以确认在我的项目中绝对没有名为 UIMoreViewController 的类(或任何接近的类)...
@TomH 是的,我测试的自定义视图控制器在“更多”下。我在 iPad 模拟器中运行了测试,横向模式,所以在“更多”之前有 6 个标签。抱歉回复晚了,我不是每天都在 ***.com 上。
不用担心延迟。我正在使用 iOS 5...但不是最新版本的 Xcode(下载量很大...)所以我会尝试更新它。
这是我在网上找到的一个小头文件,显示 UIMoreNavigationController 可能确实存在,但对于所有意图和目的来说它只是私有的......我可能必须找到另一种方法来做我正在做的事情。 github.com/comex/spirit/blob/master/igor/headers/dumpedUIKit/…
(抱歉评论批评)我认为 UIMoreNavigationController 可能是导航控制器,当您单击选项卡栏上的“更多”时,它会显示要按下的选项卡列表。当我执行 self.parentViewController 时它出现的原因是因为我手动制作的导航控制器作为一个孩子被推送到这个“更多导航控制器”上,所以当它的行在“更多”选项卡列表中被点击时它会出现。明天我会再做一些测试,看看是不是这样。【参考方案3】:
只是为了确认一个有同样的问题。我相信使用 setViewController: 在 UIMoreNavigationController 已由 UITabBarController 创建的情况下被破坏。问题是在更改选项卡栏的视图控制器时,导航控制器越多没有正确维护 - 控制器层次结构被破坏。我已向 Apple 提交了错误,但尚未收到回复。
哈拉尔【讨论】:
是的,我在经过大量测试后发现了这个问题,并以这里的答案为指导,尽管它们并不是最佳的。最后一个与 UIViewController 成为孤儿有关的问题。所以我保留了我自己添加到 TabBarController 的所有 UIViewController 的副本,而不是使用它以 viewControllers 属性的形式提供的列表。以上是关于UIMoreNavigationController 和 UITabBarController 的问题的主要内容,如果未能解决你的问题,请参考以下文章