iOS:从 XIB 添加导航栏

Posted

技术标签:

【中文标题】iOS:从 XIB 添加导航栏【英文标题】:iOS: Adding navigation bar from XIB 【发布时间】:2012-10-25 14:13:11 【问题描述】:

我已经看到了这个问题,并通过在代码中手动创建 UINavigationController 来解决它。有人可以告诉我,当我从 XIB 的属性检查器添加导航栏 - > 将顶部栏设置为黑色导航栏时,它会显示在 XIB 中,但是当我运行程序时,它不会出现!我注意到 self.NavigationController 即将为零,所以我在我的 XIB 中添加了 UINavigationController 并分配了 NIB,但它仍然为零!这有什么问题?我需要任何其他设置吗?

[编辑1]

我尝试像下面这样添加它并且它可以工作,但我希望父类自动将旋转和外观事件转发给子控制器。如果我关注它,它不会发送它们,因为我将 nvc 添加为子而不是市场列表视图控制器。所以我想我必须继承 UINavigationController。请参阅 EDIT2。

self.marketsListViewController = [[MarketsListViewController alloc] initWithNibName:@"MarketsListViewController" bundle:nil];
UINavigationController *nvc = [[UINavigationController alloc] initWithRootViewController:self.marketsListViewController];
nvc.navigationBar.barStyle = UIBarStyleBlack;
[self.marketsListView addSubview:nvc.view];

[self addChildViewController:nvc];
[nvc didMoveToParentViewController:self];

[编辑2]

我已将marketsListViewController 子类化为UINavigationController,并认为以下会起作用,但事实并非如此。它只显示导航栏,UITableView 不显示!

self.marketsListViewController = [[MarketsListViewController alloc] initWithNibName:@"MarketsListViewController" bundle:nil];
self.marketsListViewController.navigationBar.barStyle = UIBarStyleBlack;
[self.marketsListView addSubview:self.marketsListViewController.view];

[self addChildViewController:self.marketsListViewController];
[self.marketsListViewController didMoveToParentViewController:self];

[编辑3]

我在 Edit1 中错了,当我将子控制器添加为导航控制器的根控制器时,子控制器不会获得旋转事件。父母仍然自动发送所有事件,这就是我想要的! :)

【问题讨论】:

【参考方案1】:

当我从 XIB 添加导航栏时,有人可以告诉我吗 属性检查器 - >将顶部栏设置为黑色导航栏,它得到 显示在XIB中,但是当我运行程序时,它没有出现!

您在 .xib 文件中看到的内容只是为了帮助您正确布局并很好地了解它的外观。当您的应用程序使用导航栏时,导航栏几乎总是由导航视图控制器 (UINavigationController) 管理。导航控制器托管的视图控制器不担心导航栏——它们的视图层次结构位于导航栏下方的空间中。

因此,正确在您的应用中获取导航栏的方法几乎可以肯定是使用导航控制器。如果您只有一个视图控制器,请将导航控制器的根视图控制器设置为(注意:window 的根视图控制器将是导航视图控制器)。您可以通过设置导航栏的样式从视图控制器更改栏的外观:

self.navigationController.navigationBar.barStyle = UIBarStyleBlack;

更新:在您发布的代码中,您只是创建了一个新的导航控制器,但没有对其进行任何操作。我在上面提到了一个事实,即(在大多数情况下)导航控制器应该是窗口的根视图控制器。在代码中创建导航控制器很好,但您通常会在应用程序委托中进行,一旦创建它,​​您会将其设置为窗口的根视图控制器。这是一个从 Xcode 的主/详细模板(无情节提要)新建的项目中借用的示例:

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

    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    // Override point for customization after application launch.

    MasterViewController *masterViewController = [[MasterViewController alloc] initWithNibName:@"MMMasterViewController" bundle:nil];
    self.navigationController = [[UINavigationController alloc] initWithRootViewController:masterViewController];
    self.window.rootViewController = self.navigationController;
    [self.window makeKeyAndVisible];
    return YES;

注意,在创建窗口和导航控制器后,代码将导航控制器设置为窗口的根视图控制器。

【讨论】:

感谢@Celeb 消除我的疑虑!我已经编辑了这个问题。请看一看。我在容器视图中有很多屏幕,其中几个有导航栏。 MarketsListViewController 是问题中 XIB 中显示的视图控制器。 Self 表示容器视图控制器。 嗨@Celeb 不幸的是我不能在 AppDelegate 中这样做,因为它不是我拥有的唯一视图控制器。父(容器)视图控制器没有导航栏。它有大约 8-10 个子控制器,其中几个必须有导航栏才能启用嵌套视图。但无论如何,我认为我更接近解决方案。如果您看到 Edit1,它可以工作,但我无法使用它,因为我希望子控制器自动接收父级转发的旋转事件。所以我将我的视图控制器子类化为 UINavigationController 并做了同样的事情,但这不起作用!它只显示导航栏!! @AppleDeveloper 抱歉,我无法清楚地了解您在这里要做什么。子类化UINavigationController 并不常见——这可能不是正确的做法。如果您还没有,我强烈建议您阅读 View Controller Programming Guide。 @Celeb 很抱歉造成混乱。简而言之,EDIT1 代码工作得非常好。在该代码中,我创建了使用根视图控制器-marketsListViewController 初始化的 NavigationController。所以基本上我已经将导航控制器作为子控制器添加到父控制器而不是市场列表视图控制器,因此,市场列表视图控制器类将不会获得所需的事件!我认为这种方法的替代方法是子类化导航控制器 - EDIT2。此解决方案仅在原始问题中显示我的 XIB 的导航 abr 而不是 uitableview。我希望我很清楚。 @Celeb 关于查看编程指南,我读了很多遍,我认为我是一个优秀的程序员 :) 我了解到,当你试图实现某些目标时,你不会重新发明***。可能 Apple 已经为您创建了类。在这种情况下,我的要求是 UINavigationController 带有导航栏,并且仍然希望我的父母将所需的事件转发给孩子,因此子类化 UINavigationController 应该是一个不错的选择!不是吗?

以上是关于iOS:从 XIB 添加导航栏的主要内容,如果未能解决你的问题,请参考以下文章

iOS:从导航栏中删除以编程方式添加的搜索栏

导航栏项目在 ios 8.1 中缩小到角落

xib 中的自动布局 - 子视图的高度与导航栏和标签栏之间的空间成正比

ios:如何删除导航栏上方的空白栏?

如何在 iOS 7 中设置导航栏的色调颜色

如何将三个按钮栏项目添加到 xib 文件