【问题标题】:Having a UITabBar AND a UINavigationController in an app?在应用程序中有一个 UITabBar 和一个 UINavigationController?
【发布时间】:2011-01-21 07:16:51
【问题描述】:

大家好,我是 iPhone 开发的新手,我不了解整个 UINavigationController 和 UITabBarController 的想法。一个可以替代另一个 - Tweetie 等应用如何将两者结合起来?

我想让我的应用程序在底部有一个持久的标签栏(这似乎正在工作),但在顶部还有一个导航栏,可以在不移除标签栏的情况下将视图推送/弹出到屏幕上。

  • 我怎样才能做到这一点?
  • 就所有这些控制器而言,就我的 MainWindow.xib 而言,IB 中的层次结构应该是什么样的?
  • 这里的最佳做法是什么?

非常感谢,

【问题讨论】:

标签: iphone iphone-sdk-3.0 uinavigationcontroller uitabbarcontroller


【解决方案1】:

将向导用于选项卡栏应用程序,并正常进行设置。在要添加导航控制器的任何选项卡中,使用库在 XIB 中创建它。我的 XIB 有:

- 文件的所有者 DescriptiveNameNavViewController
- 急救人员
- 查看 UIVIew
- 导航控制器 UINavigationController
  - 导航栏 UINavigationBar

请注意,视图中没有任何内容。请参阅下面的 viewDidLoad,了解 UINavigationController 连接到 UIView 的位置。

在 Tab 的 ViewController 的头文件中(我在这里称为 DescriptiveNameNavViewController - 对此没有特定的标准,但我使用 [Something]NavViewController 来提醒我此 ViewController 包含一个导航控制器导航堆栈。这是我在向导生成的 MainWindow.xib 中设置的控制器名称)设置一个 UINavigationController * IBOutlet,它附加了 XIB 中的导航控制器:

@interface DescriptiveNameNavViewController : UIViewController {
    UINavigationController *navigationController;
}
@property (nonatomic, retain) IBOutlet UINavigationController *navigationController;

@end

在 DescriptiveNameNavViewController 的控制器中,执行以下操作:

- (void)viewDidLoad {
    [super viewDidLoad];
    [[self view] addSubview:[navigationController view]];
    DescriptiveNameController *aController = [[[DescriptiveNameController alloc ] initWithNibName:@"DescriptiveNameController" bundle:nil ] autorelease];
    aController.title = @"Descriptive Title";

//
//  app stuff goes here.
//

    [self.navigationController pushViewController:aController animated:YES];
    [self.navigationController setDelegate:self];
}

在 DescriptiveNameNavViewController 中设置委托非常重要,因为否则您将无法获得在 DescriptiveNameViewController 实例中调用的方法以及您推入导航控制器堆栈的任何其他内容。

在 DescriptiveNameNavViewController 中,实现 UINavigationControllerDelegate 方法,如下所示:

- (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
    if ([viewController respondsToSelector:@selector(viewDidAppear:)]) {
        [viewController viewDidAppear:animated];
    }
}

这将导致消息像您期望的那样传播到 UINavigationController 内的控制器。人们遇到的许多问题似乎是因为 viewDidAppear: 或其他方法没有被推送到 NavigationController 中的 ViewController 上调用。

无论如何,如果更多细节有帮助,请告诉我。

【讨论】:

  • 我遵循了这个,但它不起作用。仍然没有在概念层面上得到这个。当我启动应用程序并单击第二个选项卡时,它只是加载视图,而不是带有导航控制器的视图。此外,您在标头中缺少 UINavigationControllerDelegate 协议。为什么navigationController在界面中没有定义为IBOutlet,而在property语句中定义为IS?
  • @property 语句中只有一个 IBOutlet,因为它是接口构建器从中获取的。这是一个空宏。如果您在第二个面板上看到一个空视图,那是因为在 viewDidLoad 中加载导航控制器不起作用。无论如何,如果 chrissr 的解决方案对您有用,只需注意 viewWill* 和 viewDid* 方法不会传播到您的子视图,如果是,请实施委托。 (缺少的委托协议是错误粘贴,但无论如何都会调用这些方法。)
【解决方案2】:

只需将视图控制器包装在UINavigationController 中,并将UINavigationController 放在UITabBar 中。 这对你来说很好用……

例子:

NSMutableArray *tabBarViewControllers = [[NSMutableArray alloc] initWithCapacity:2];

tabBarController = [[UITabBarController alloc] init];
[tabBarController setDelegate:self];

UINavigationController *navigationController = nil;
navigationController = [[UINavigationController alloc] initWithRootViewController:<Your View controller1>];
[tabBarViewControllers addObject:navigationController];
[navigationController release];
navigationController = nil;

navigationController = [[UINavigationController alloc] initWithRootViewController:<Your View controller2>];
[tabBarViewControllers addObject:navigationController];
[navigationController release];
navigationController = nil;

tabBarController = tabBarViewControllers;
[tabBarViewControllers release];
tabBarViewControllers = nil;

【讨论】:

  • 这更有意义,每个视图控制器都可以有自己的导航控制器来弹出/推送视图。谢谢!
  • @Manjunath:这样,我没有成功用两个不同的名称命名导航栏和标签栏项目。有没有办法做到这一点?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多