向 UINavigationController 添加按钮的问题

Posted

技术标签:

【中文标题】向 UINavigationController 添加按钮的问题【英文标题】:Issue with adding buttons to UINavigationController 【发布时间】:2013-08-22 20:45:50 【问题描述】:

这就是我制作导航栏的方式:

- (void)viewDidLoad

    [super viewDidLoad];
    UINavigationController *navBar = [[UINavigationController alloc] init];
    [navBar willMoveToParentViewController:self];
    navBar.view.frame = CGRectMake(0, 0, 320, 44);
    [self.view addSubview:navBar.view];
    [self addChildViewController:navBar];
    [navBar didMoveToParentViewController:self];
    ...

我读到的所有地方都说这是添加按钮的方式:

UIBarButtonItem *button = [[UIBarButtonItem alloc]initWithTitle:@"test" style:UIBarButtonItemStyleBordered target:self action:@selector(print_message:)];
self.navigationItem.rightBarButtonItem = button;
[button release];

但该按钮未显示在导航栏上。这段代码有什么问题?

【问题讨论】:

【参考方案1】:

除非您正在构建一个自定义容器视图控制器(这是一种相对罕见的事情),否则您不应该在内容控制器的-viewDidLoad 中构建 UINavigationController。虽然它会为您提供导航栏,但您的视图控制器父子关系将是倒退的:您的内容控制器将包含导航控制器,而不是相反。

相反,您需要在应用程序启动过程的早期创建导航控制器 - 可能在您的应用程序委托中,或者在您的主​​情节提要中(如果您正在使用导航控制器)。确保新的导航控制器将您的内容控制器作为其根控制器(通常通过-initWithRootViewController:)。那么你的self.navigationItem 配置就可以正常工作了。

【讨论】:

我应该在 AppDelegate 的什么地方添加它?它会在 ApplicationDidFinishLaunching 中吗?【参考方案2】:

您应该以不同的方式创建导航栏:

在你的 xxxAppDelegate.m 中编辑这个方法:

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

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

//This is the ViewController of the view you want to be the root
xxxViewController *tvc = [[xxxViewController alloc]init];

//Now you have to initialize a UINavigationController and set its RootViewController
UINavigationController *nvc = [[UINavigationController alloc]initWithRootViewController:tvc];

//Now set the RootViewController to the NavigationViewController
[[self window]setRootViewController:nvc];


self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
return YES;

所以现在你有了一个合适的 NavigationController。如果您在 viewDidLoad 方法中执行此操作,则每次重新加载视图时都会生成 NavigationController。

现在在你的 xxxViewController.m 中编辑你的 init 方法:

- (id)init

...
if (self) 
 //Create a UINavigationItem
 UINavigationItem *n = [self navigationItem];

 //Create a new bar button item 
 UIBarButtonItem *button = [[UIBarButtonItem alloc]initWithTitle:@"test"    style:UIBarButtonItemStyleBordered target:self action:@selector(print_message:)];
 [[self navigationItem]setRightBarButtonItem:button];

return self;

现在应该显示一个带有 UIBarButtonItem 的正确 NavigationBar。

【讨论】:

好的,我对ApplicationDidFinishLaunching 方法有疑问。有一个返回void,还有一个返回boolean,最后有WithOptions。在空白处,我有[window addSubview:myViewController.view];[window makeKeyAndVisible];。此代码会干扰该代码吗? 根据这篇文章:***.com/questions/7151378/… void 是旧版本的 applicationDidFinishLaunching。因此,如果您想保持对 ios 3 之前系统的兼容性,您可能必须在 void one 中对其进行编辑。 啊好的。那么使用IBOutlet...@property... 在.h 文件中设置ViewController 和Window 与执行上述操作有区别吗? AppDelegate 管理某些事件的内容,例如应用程序启动或关闭时。由于您在应用程序启动后立即需要 NavigationController,因此当您的应用程序收到应用程序正确启动的消息时创建它是有意义的。你在 .h 文件中做一些事情,它会像 UIBarButtonItem 一样直接影响视图。所以你可以简化它并说创建视图的全局内容在 AppDelegate 中,而特定的内容在 ViewController 中。 好的,所以我从 appdelegate.h 文件中删除了我的 viewcontroller 东西,并按照你说的做了。导航栏现在确实显示了,但视图控制器是空的。它没有显示我以前在那里的任何东西。我现在必须以不同的方式设置我的滚动视图和图像视图吗?

以上是关于向 UINavigationController 添加按钮的问题的主要内容,如果未能解决你的问题,请参考以下文章

如何在 iOS 7 上的 UINavigationController 中禁用向后滑动手势

如何向 UINavigationController 添加一个在任何子视图上方可见的视图

iOS 故事板 UINavigationController 不正确地弹出视图(向下滑动,而不是向右滑动)

UINavigationController 阴影

获取对 UINavigationController 的引用

无法在 UINavigationController 上设置后退按钮