当应用程序 rootViewController 是 tabBarController 时 UINavigationController 的奇怪行为

Posted

技术标签:

【中文标题】当应用程序 rootViewController 是 tabBarController 时 UINavigationController 的奇怪行为【英文标题】:Strange behaviour of UINavigationController when the applications rootViewController is a tabBarController 【发布时间】:2014-07-03 08:07:51 【问题描述】:

我尝试将 UIViewController 推送到 UINavigationController。 NavigationBar 发生变化(即出现后退按钮),但视图未按下 (*)。

我有一个 UITabBarController 作为我的应用程序 RootViewController。

当我切换到另一个选项卡然后切换回来时,视图 (*) 会被推送。

我以前从未见过这种行为。我的问题与this 完全相同,但是解决该问题的方法并没有解决我的问题。

最初

按行后

我知道这个问题可能与 AppDelegate 中的问题有关,因此我发布了我使用的代码。

代码:

在 AppDelegate 中:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:     (NSDictionary *)launchOptions

self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
self.window.backgroundColor = [UIColor whiteColor];
[MagicalRecord setupCoreDataStackWithStoreNamed:@"DBModel"];

/* CONTACTS LIST CONTROLLER */
BoonContactListViewController *contactListViewController = [[BoonContactListViewController alloc] initWithNibName:nil bundle:nil];
UINavigationController *contactListNavigationController = [[UINavigationController alloc] initWithRootViewController:contactListViewController];
[contactListNavigationController setValue:[[BoonNavigationBar alloc]init] forKeyPath:@"navigationBar"];
contactListNavigationController.tabBarItem.title = [NSLocalizedString(@"CONTACTS", nil) capitalizedString];
contactListNavigationController.tabBarItem.image = [UIImage imageNamed:@"menu_contacts.png"];


/* INVITATIONS */

BoonInvitationListViewController *invitationListController = [[BoonInvitationListViewController alloc] initWithNibName:nil bundle:nil];
UINavigationController *invitationNavigationController = [[UINavigationController alloc] initWithRootViewController:invitationListController];
[invitationNavigationController setValue:[[BoonNavigationBar alloc]init] forKeyPath:@"navigationBar"];
invitationNavigationController.tabBarItem.title = [NSLocalizedString(@"SETTINGS", nil) capitalizedString];
invitationNavigationController.tabBarItem.image = [UIImage imageNamed:@"menu_invitations.png"];

/* SETTINGS */
BoonSettingsViewController *settingsViewController = [[BoonSettingsViewController alloc] initWithNibName:nil bundle:nil];
UINavigationController *settingsNavigationController = [[UINavigationController alloc] initWithRootViewController:settingsViewController];
[settingsNavigationController setValue:[[BoonNavigationBar alloc]init] forKeyPath:@"navigationBar"];
settingsNavigationController.tabBarItem.title = [NSLocalizedString(@"SETTINGS", nil) capitalizedString];
settingsNavigationController.tabBarItem.image = [UIImage imageNamed:@"menu_settings.png"];



/* TAB BAR */
BoonTabBarViewController *tabBarController = [[BoonTabBarViewController alloc] init];
tabBarController.viewControllers = @[contactListNavigationController, invitationNavigationController, settingsNavigationController];

[self.window setRootViewController:tabBarController];

[self.window makeKeyAndVisible];

[tabBarController showLogin];
return YES;

编辑:

在我试图推送的 viewController 中,viewWillAppearviewDidLoadviewDidAppear 都没有被调用。

如果我使用 presentViewController: animated: completion: 我会得到首选行为,但不是 id 而不是

编辑 2

我如何推动我的新 VC

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath


BoonContactInfoViewController *contactInfoViewController = [[BoonContactInfoViewController alloc] initWithNibName:nil bundle:nil];
NSLog(@"NAV %@", self.navigationController);
[self.navigationController pushViewController:contactInfoViewController animated:YES];

编辑 3 只有初始选项卡无法推送...如果我交换第一个和第二个选项卡的位置,我可以使用上面的方式推送视图控制器。

编辑 4 如果我(在我的 tabBarController 中)调用它会起作用

self.selectedIndex = 1;
self.selectedIndex = 0;

编辑 5

- (void)showLogin


if([BoonUserHandler getLogin].length > 0 && [BoonUserHandler getPassword].length > 0)
    return;

BoonWelcomeViewController *welcomeWC = [[BoonWelcomeViewController alloc] initWithNibName:nil bundle:nil];

UINavigationController *welcomeNavigationController = [[UINavigationController alloc] initWithRootViewController:welcomeWC];
[welcomeNavigationController setNavigationBarHidden:YES];


[self presentViewController:welcomeNavigationController animated:NO completion:nil];

【问题讨论】:

我相信问题可能出在 BoonContactListViewController 代码中。用户按下单元格后,您以什么方式推送新屏幕? 更新了我的问题,谢谢 viewDidLoad 被调用,因为您强制视图按[contactInfoViewController view]; 行加载。为什么叫它?你覆盖了[BoonContactInfoViewController loadView] 吗? 你是对的,现在什么都没有调用..,出于调试目的,我忘记了那里的那一行。更新的问题。 谢谢,能否提供showLogin方法的代码? 【参考方案1】:

您正在为哪个版本的 ios 开发?

我首先要问你为什么要在导航栏中使用:

[settingsNavigationController setValue:[[BoonNavigationBar alloc]init] forKeyPath:@"navigationBar"];

而不是iOS5+的UINavigationController方法:

- (instancetype)initWithNavigationBarClass:(Class)navigationBarClass toolbarClass:(Class)toolbarClass

但我的总体建议是删除所有这些代码并使用情节提要。这看起来是个绝佳的机会。

【讨论】:

iOS 7+。我真的不喜欢故事板。我更喜欢以编程方式做事并使用 xibs 进行基本布局。现在使用您提供的方法代替 setValue: forKeyPath: ..+1 作为补充方法【参考方案2】:

我认为您推错了导航控制器,这就是它显示此问题的原因..

你必须从标签控制器中获取正确的导航控制器

  self.tabBarController.selectedIndex = 0;

只需更改选项卡控制器选择的索引

【讨论】:

以上是关于当应用程序 rootViewController 是 tabBarController 时 UINavigationController 的奇怪行为的主要内容,如果未能解决你的问题,请参考以下文章

Swift:当应用程序在后台运行时,无法使用 pushNotification 的信息刷新 rootViewController

当用户按下主页按钮但在应用程序进入后台之前,如何从应用程序窗口的 rootViewController 呈现 viewController? [复制]

当 rootViewController 不是 UINavigationController 时推送视图

ios:更改 window.rootViewController 和内存管理

当 UINavigationController 通过 Storyboard 模态呈现时,它的 rootViewController 与它没有连接

当 UITabBar 不是 rootViewController 时,如何以编程方式将 UITabBar 与具有 NIB 的不同 ViewController 链接