【问题标题】:How to add a Navigation Controller with Interface Builder?如何使用 Interface Builder 添加导航控制器?
【发布时间】:2011-01-12 15:29:48
【问题描述】:

1.步骤: 创建一个新的 UIViewController:
- Xcode -> 新建文件... -> Cocoa Touch 类 -> UIViewController
- 名称:MyViewController

2。步骤: 将“导航控制器”(UINavigationController)从库中拖放到 MyViewController.xib

3.Step:我确定,我必须做一些事情才能正确连接导航控制器,不是吗?

4.Step:尝试以模态对话框的形式启动新的 View Controller:

MyViewController *myViewController = [[MyViewController alloc] initWithNibName:@"MyViewController" bundle:nil];
NSLog(@"navContr: %@", myViewController.navigationController);
[self.navigationController presentModalViewController: myViewController animated:YES]; 

结果:“navContr: nil”

5.Step:可以看到新的模态视图(MyViewController),但是没有NavigationController,也没有UINavigationBar。

非常感谢您的帮助!


更新 1:

6.Step:我将新的 UIViewController (ViewNavi2) 设置为“根视图控制器”:

7.Step:我在 MyViewController 类中定义了一个IBOutlet UINavigationController *navigationController 并配置了xib:Navigation Controller -> Connections -> Referencing Outlets

但是我的导航控制器仍然是 nil :-(

MyViewController *myViewController = [[MyViewController alloc] initWithNibName:@"MyViewController" bundle:nil];
NSLog(@"navContr: %@", myViewController.navigationController);
// -> "navContr: nil"

【问题讨论】:

  • here是添加导航控制器的简单教程

标签: iphone objective-c ios interface-builder uinavigationcontroller


【解决方案1】:

我还想在 NIB 文件中包含导航控制器,但 Apple 文档所说的只是它“不是最佳的”,而没有实际解释如何做到这一点。我希望我的主选项卡式窗口能够调用包含典型导航控件的模式窗口,而无需以编程方式定义导航控制器。我将分享我是如何做到的。

您的代码与我的非常相似,因为我还在 MyViewController 中定义了 IBOutlet UINavigationController *navigationController。在 Interface Builder 中,我只是在根视图控制器中定义了我的视图,并将 File's Owner->view 设置为该视图定义。

与您的代码类似,我在父窗口中执行了以下操作:

MyViewController *myViewController = [[MyViewController alloc] initWithNibName:@"MyViewController" bundle:nil];
[self presentModalViewController:myViewController animated:YES];

(我在self上调用presentModelViewController,我不知道你为什么有self.navigationController。)当我测试这个时,结果是我的视图是从NIB文件中加载的,但是导航栏不见了。 MyViewController 中的另一行代码修复了这个问题:

- (void)viewDidLoad {
    [super viewDidLoad];

    [self setView:myNavigationController.view];

}

我在这里所做的只是将 MyViewController 的视图设置为指向 myNavigationController.view,其中包含 NIB 文件中定义的所有内容,包括导航控制器。

【讨论】:

  • 非常感谢您的精彩回答!我相信这会帮助很多人! :-) @all:请投票
  • @Henry 我尝试做一些非常相似的事情。这为我节省了很多工作。谢谢!
  • 非常漂亮的解释。谢谢。
  • 你能显示 xib 文件的图像吗?我们是否假设在最顶层有一个视图(谁是视图的所有者)和另一个 UINavigationController?那么我们实际的 ui 对象会去哪里,在 UINavigationController 的视图或原始视图下?
【解决方案2】:

在 XCode 中查看“基于导航的应用程序”的模板。 (New Project -> Navigation-based Application) 然后在 Interface Builder 中打开 MainWindow.xib。虽然它不是视图,但可以将其视为您在步骤 1 中创建的视图控制器。然后查看检查器中引用的“根视图控制器”,并查看它是如何连接到“根视图控制器”笔尖的属性检查器和身份检查器中的“RootViewController”类。

您需要将要显示的内容放在您的“RootViewController”版本中的导航根目录中。通常,接下来显示的控制器是“DetailViewController”。同样,通读模板提供的示例代码,您将了解如何开始。查看 RootViewController.m 示例模板中 didSelectRowAtIndexPath 中的注释代码。您需要创建自己的视图控制器作为 DetailViewController。

希望这会为您解决问题。

//根据您的评论进行编辑//
Apple 文档说,如果你想使用 IB 来制作导航控制器,你应该把它们放在你的 MainWindow.xib 中。我正在修补这样一个事实,即您不能将 NavigationController 作为 UIView 对象的子视图。鉴于您从哪里开始,您可以做的是使用 IB 将导航栏对象添加到您的视图控制器,然后从那里控制事物。

来自 Apple 文档“虽然您也可以从主 nib 文件(或任何其他 nib 文件)加载独立或模态显示的导航控制器,但这样做并不是最佳选择。在这些情况下,创建导航通常更容易控制器在使用点以编程方式。”

//更多编辑// 在 XCode4 中,项目模板现在称为“Master Detail”项目。这是因为它将在 iPad 中设置为拆分视图控制器,但在 iPhone 中仍是常规导航项目。我在答案中引用“RootViewController”的地方,你现在会发现一个叫做“MasterViewController”的东西

【讨论】:

  • 非常感谢您的帮助!我仔细分析了基于导航的应用程序。是的,有一个带有工作导航控制器的 MainWindow.xib。它与 AppDelegate 连接,这是我的 MyViewController 的唯一区别。在模板项目中,您看不到 MainWindow.xib 是如何被初始化的,也许我的代码 "MyViewController *myViewController = [[MyViewController alloc] initWithNibName:@"MyViewController" bundle:nil];"是错的。请在我的问题中查看“更新 1”。
  • 来自 Apple 文档“虽然您也可以从主 nib 文件(或任何其他 nib 文件)加载独立或模态呈现的导航控制器,但这样做并不是最佳选择。在这些情况下,通常是更容易在使用时以编程方式创建导航控制器。”
  • 是的,你是对的,以编程方式创建导航控制器会更容易,但我必须使用 Interface Builder 来完成。你可以在这里找到原因:stackoverflow.com/questions/4604647/…你还有什么想法给我吗?
  • 在您提到的另一个问题中,当您将视图控制器/导航控制器放入 MainWindow.xib 时,它似乎可以正常工作。我建议通过漂亮的 nib2objc (github.com/akosma/nib2objc) 软件运行以这种方式工作的软件。这应该会为您提供一些客观的 C 文件,您可以查看这些文件以了解不同元素是如何创建和相互关联的。
  • Apple 已经从 Xcode4 中删除了创建该项目的能力 - 即使您仍然必须为所有 iOS 4.0/4.1/4.2 项目执行此操作。如果您可以链接到示例项目,或者解释该项目中到底发生了什么,将会很有帮助
【解决方案3】:

下一个代码不会给你任何有效的对象。

NSLog(@"navContr: %@", myViewController.navigationController);

原因是UIViewController的navigationController属性only returns a navigation controller if the view controller is in its stack. This property is nil if a navigation controller cannot be found.你的view controller不在navigation controller的栈中。无论如何,我什至不确定您是否正确初始化了我们的导航控制器。阅读一些文档。

【讨论】:

  • 也感谢您的帮助!它接缝,“视图控制器不在其堆栈中”。是的,我认为我没有正确初始化我的导航控制器。但是如何在 Interface Builder 中做到这一点?我更新了我的问题,请查看“更新 1”。
  • 另外,如果您的视图位于导航控制器堆栈中,但您(自动)将它释放到您不应该拥有的地方,self.navigationController 可能为零。哇!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多