NavigationItem setTitle 不适用于第二级 UIViewController
在我的应用程序中,我有一个 UITabBarController ,其中 UINavigationControllers 初始化如下
UINavigationController *newsNavigationController = [[UINavigationController alloc] initWithRootViewController: newsViewControler];
newsViewController 是一个 UIViewController 。 当我按下选项卡栏中的按钮以使用 newsViewController 显示导航项时,导航栏中的标题设置正常。在 newsViewController 中,我有一个在初始化后调用的方法设置。在设置方法中我这样设置标题 [[self navigationItem] setTitle:[category_c title]];
现在问题来了,在我的 newsViewController 中,我有一个 tableView,当我触摸一个单元格时,我想用所选新闻推送 UIViewController 并在导航栏显示标题。
在 UIViewController 中,我有相同的设置方法,其中我设置了如上所述的标题。问题是没有显示出来。导航项不为空,因为我可以调用 self.navigationItem.hidesBackButton = YES; ,并且它每次都会隐藏后退按钮,但不显示标题。
当触摸单元格时,我像这样创建并推送新闻 UIViewController
if(newsViewController == nil){
newsViewController = [[NewsViewController alloc] init];
[newsViewController setup];
}
[self.navigationController pushViewController: newsViewController animated:YES];
newsViewController 中的设置方法如下所示:
- (void) setup {
self.navigationItem.hidesBackButton = YES;
[self.navigationItem setTitle:@"my view"];
}
在 newsViewController 中,我有 viewDidLoad 并尝试在那里设置标题,但没有成功。
- (void)viewDidLoad { self.navigationItem.title = @"测试"; [超级viewDidLoad]; if
after [self.navigationController PushViewController: newsViewControllerAnimated:YES];
我写 [[self.navigationController.viewControllers objectAtIndex:0] setTitle:@"myTitle"];
包含 UITableView 的 UIViewController 获取标题 myTitle 而不是我触摸单元格时推送的 newsViewController 。
有什么指示吗?我不明白为什么标题设置不正确。
EDIT2:在阅读更多内容并使用调试器逐步浏览我的代码并将 rootviewcontrollers 与 childViewControllers 进行比较后,我发现在设置 self.title = @"title" 后,在 childViewController 的 viewDidLoad 方法中navigationItem 已创建,因此不是 nil 情况。在调试器中,当我展开 _navigationItem 变量时,离开 viewDidLoad 后字段 _navigationBar 为 nil,在 rootViewControllers 中,navigationBar 不为 NULL,标题也在那里。我读到,如果导航栏为空,标题将不会显示。图中是我在调试器中看到的。 替代文本 http://img138.imageshack.us/img138/1513/picture2bq.png 现在我正在朝这个方向搜索。
编辑1:下面是parentViewController、firstChildViewController 和第二个ChildViewController 的代码。 查看parentViewController(标题可以)。我按下导航栏上的一个按钮,调用 bearbeitenAction ->第一个孩子被推入(标题不显示)。在第一个ChildViewController的导航栏上,我有一个按钮,按下该按钮时会将新的ViewController推送到堆栈上(第二个ChildViewController)。第二个ChildViewController的标题不行。当我按“返回”时,将显示firstChildViewController的标题。
parentViewController:
//MARK: -
//MARK: Initialization methods
- (void) setup {
dataManipulator = [[DataManipulation alloc] init];
dataManipulator.delegate = self;
[self.tabBarItem initWithTitle:[NSString stringWithFormat:@"%@",[category_c title]] image:[UIImage newImageFromResource:[category_c icon]] tag:0];
searchResults = nil;
companyDetailsPushed = NO;
}
//MARK: -
//MARK: ViewControllerMethods
// Implement loadView to create a view hierarchy programmatically, without using a nib.
- (void) loadView {
NSLog(@"WatchlistViewController: loadView");
UIView *mainView = [[[UIView alloc] initWithFrame:CGRectMake(0, 0, [[UIScreen mainScreen] applicationFrame].size.width, [[UIScreen mainScreen] applicationFrame].size.height)] autorelease];
[mainView setBackgroundColor:[UIColor whiteColor]];
mainView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
mainView.contentMode = UIViewContentModeScaleToFill;
[mainView setAutoresizesSubviews:YES];
companiesTable = [[UITableView alloc] initWithFrame:CGRectMake(0, 44, [[UIScreen mainScreen] applicationFrame].size.width, 322)];
companiesTable.delegate = self;
companiesTable.dataSource = self;
[mainView addSubview:companiesTable];
[companiesTable release];
self.view = mainView;
}
- (void)viewDidLoad {
[super viewDidLoad];
if(![[category_c subtitle] isEqualToString:@""]) {
self.title = [category_c subtitle];
}
else {
self.title = [category_c title];
}
}
- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if(companyDetailsViewController == nil) {
companyDetailsViewController = [[CompanyDetailsScrollViewController alloc] init];
[companyDetailsViewController setup];
}
[watchlistDoneBtn setHidden:TRUE];
companyDetailsPushed = YES;
if(viewMode == SearchViewMode)
[companyDetailsViewController setCompany:[searchResults objectAtIndex:indexPath.row]];
else if(viewMode == WatchlistViewMode)
[companyDetailsViewController setCompany:[[[Financial_deAppDelegate sharedAppDelegate] watchlistCompanies] objectAtIndex:indexPath.row]];
[[self navigationController] pushViewController:companyDetailsViewController animated:YES];
}
- (void) bearbeitenAction:(UIButton *) sender {
NSLog(@"Berbeiten btn was pressed");
if(berbeitenViewController == nil){
berbeitenViewController = [[BerbeitenViewController alloc] init];
[berbeitenViewController setup];
}
[self.navigationController pushViewController:berbeitenViewController animated:YES];
}
代码中的firstChildViewController = berbeitenViewController:
- (void) setup {
self.navigationItem.hidesBackButton = YES;
}
// Implement loadView to create a view hierarchy programmatically, without using a nib.
- (void)loadView {
NSLog(@"BerbeitenViewController: loadView");
UIView *mainView = [[[UIView alloc] initWithFrame:CGRectMake(0, 0, [[UIScreen mainScreen] applicationFrame].size.width, [[UIScreen mainScreen] applicationFrame].size.height)] autorelease];
[mainView setBackgroundColor:[UIColor darkGrayColor]];
mainView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
mainView.contentMode = UIViewContentModeScaleToFill;
[mainView setAutoresizesSubviews:YES];
berbeitenBackBtn = [[UIButton alloc] initWithFrame:CGRectMake(5, 23, 69, 36)];
[berbeitenBackBtn setBackgroundImage:[UIImage newImageFromResource:@"back_btn.png"] forState:UIControlStateNormal];
[berbeitenBackBtn addTarget:self action:@selector(popViewController:) forControlEvents:UIControlEventTouchUpInside];
[berbeitenBackBtn setEnabled:TRUE];
[self.navigationController.view addSubview:berbeitenBackBtn];
[berbeitenBackBtn release];
berbeitenAddBtn = [[UIButton alloc] initWithFrame:CGRectMake(260, 23, 55, 36)];
[berbeitenAddBtn setBackgroundImage:[UIImage newImageFromResource:@"bearbeiten_add_btn.png"] forState:UIControlStateNormal];
[berbeitenAddBtn addTarget:self action:@selector(addCompany:) forControlEvents:UIControlEventTouchUpInside];
[berbeitenAddBtn setEnabled:TRUE];
[self.navigationController.view addSubview:berbeitenAddBtn];
[berbeitenAddBtn release];
companiesTable = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, [[UIScreen mainScreen] applicationFrame].size.width, 366)];
companiesTable.delegate = self;
companiesTable.dataSource = self;
[mainView addSubview:companiesTable];
[companiesTable release];
self.view = mainView;
}
- (void)viewDidLoad {
NSLog(@"BerbeitenViewController viewDidLoad");
[super viewDidLoad];
self.title = @"Edit watchlist";
}
//MARK: Buttons actions
- (void) popViewController:(UIButton *) sender {
NSLog(@"Pop BerbeitenViewController");
[self.navigationController popViewControllerAnimated:YES];
}
- (void) addCompany:(UIButton *) sender {
NSLog(@"Berbeiten addCompany btn pushed");
if(searchViewController == nil){
searchViewController = [[SearchViewController alloc] init];
[searchViewController setup];
}
[self.navigationController pushViewController:searchViewController animated:YES];
}
代码中的secondChildViewController = searchViewController
- (void) setup {
self.navigationItem.hidesBackButton = YES;
}
// Implement loadView to create a view hierarchy programmatically, without using a nib.
- (void)loadView {
NSLog(@"BerbeitenViewController: loadView");
UIView *mainView = [[[UIView alloc] initWithFrame:CGRectMake(0, 0, [[UIScreen mainScreen] applicationFrame].size.width, [[UIScreen mainScreen] applicationFrame].size.height)] autorelease];
[mainView setBackgroundColor:[UIColor darkGrayColor]];
mainView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
mainView.contentMode = UIViewContentModeScaleToFill;
[mainView setAutoresizesSubviews:YES];
searchViewBackBtn = [[UIButton alloc] initWithFrame:CGRectMake(5, 23, 69, 36)];
[searchViewBackBtn setBackgroundImage:[UIImage newImageFromResource:@"back_btn.png"] forState:UIControlStateNormal];
[searchViewBackBtn addTarget:self action:@selector(popViewController:) forControlEvents:UIControlEventTouchUpInside];
[searchViewBackBtn setEnabled:TRUE];
[self.navigationController.view addSubview:searchViewBackBtn];
[searchViewBackBtn release];
self.view = mainView;
}
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[super viewDidLoad];
self.title = @"Edit Watchlist";
}
in my app i have an UITabBarController with UINavigationControllers initialized like this
UINavigationController *newsNavigationController = [[UINavigationController alloc] initWithRootViewController: newsViewControler];
newsViewController is an UIViewController.
When i press the button in the tabbar to show the navigation item with the newsViewController the title in the navigation bar is set ok. in the newsViewController i have a method setup that i call after init. In the setup method i set the title like this[[self navigationItem] setTitle:[category_c title]];
The problem comes now, in my newsViewController i have a tableView, when i touch a cell i want to push a UIViewController with the selected news and in the navigation bar to show the title.
In the UIViewController i have the same setup method in which i setup the title like above. The problem is that is not shown. The navigation item is not null because i can call self.navigationItem.hidesBackButton = YES;
and it hides the backbutton every time but the title isn't shown.
I create and push the news UIViewController like this when a cell is touched
if(newsViewController == nil){
newsViewController = [[NewsViewController alloc] init];
[newsViewController setup];
}
[self.navigationController pushViewController: newsViewController animated:YES];
The setup method in the newsViewController looks like this:
- (void) setup {
self.navigationItem.hidesBackButton = YES;
[self.navigationItem setTitle:@"my view"];
}
in the newsViewController i have viewDidLoad and tried to set the title there but with no success.
- (void)viewDidLoad {
self.navigationItem.title = @"Test";
[super viewDidLoad];
}
if after [self.navigationController pushViewController: newsViewController animated:YES];
i write [[self.navigationController.viewControllers objectAtIndex:0] setTitle:@"myTitle"];
the UIViewController that contains the UITableView gets the title myTitle instead of the newsViewController that i pushed when i touched the cell.
any pointers? i can't understand why the title is not set correctly.
EDIT2: After reading a little more and going through my code with the debugger step by step and comparing the rootviewcontrollers with the childViewControllers i've observed that in the viewDidLoad method of the childViewController after setting self.title = @"title" the navigationItem is created so it's not the nil situation. In the debugger when i expand the _navigationItem variable the field _navigationBar is nil after leaving viewDidLoad, in the rootViewControllers the navigationBar is NOT NULL and the title is there. I read that if the navigationBar is null the title will not show up. In the image is what i've seen in the debuger. alt text http://img138.imageshack.us/img138/1513/picture2bq.png now i'm searching in this direction.
EDIT1: below is the code for the parentViewController, firstChildViewController and second ChildViewController.
the parentViewController is viewed(the title is OK). I press a button on the navigationBar that calls bearbeitenAction -> the first child is pushed(title is not showed). On the navigation bar of the firstChildViewController i have a button that when is pressed pushes a new ViewController on the stack(secondChildViewController). The title of the second ChildViewController is not ok. When i press Back the title of the firstChildViewController is showed Ok.
parentViewController:
//MARK: -
//MARK: Initialization methods
- (void) setup {
dataManipulator = [[DataManipulation alloc] init];
dataManipulator.delegate = self;
[self.tabBarItem initWithTitle:[NSString stringWithFormat:@"%@",[category_c title]] image:[UIImage newImageFromResource:[category_c icon]] tag:0];
searchResults = nil;
companyDetailsPushed = NO;
}
//MARK: -
//MARK: ViewControllerMethods
// Implement loadView to create a view hierarchy programmatically, without using a nib.
- (void) loadView {
NSLog(@"WatchlistViewController: loadView");
UIView *mainView = [[[UIView alloc] initWithFrame:CGRectMake(0, 0, [[UIScreen mainScreen] applicationFrame].size.width, [[UIScreen mainScreen] applicationFrame].size.height)] autorelease];
[mainView setBackgroundColor:[UIColor whiteColor]];
mainView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
mainView.contentMode = UIViewContentModeScaleToFill;
[mainView setAutoresizesSubviews:YES];
companiesTable = [[UITableView alloc] initWithFrame:CGRectMake(0, 44, [[UIScreen mainScreen] applicationFrame].size.width, 322)];
companiesTable.delegate = self;
companiesTable.dataSource = self;
[mainView addSubview:companiesTable];
[companiesTable release];
self.view = mainView;
}
- (void)viewDidLoad {
[super viewDidLoad];
if(![[category_c subtitle] isEqualToString:@""]) {
self.title = [category_c subtitle];
}
else {
self.title = [category_c title];
}
}
- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if(companyDetailsViewController == nil) {
companyDetailsViewController = [[CompanyDetailsScrollViewController alloc] init];
[companyDetailsViewController setup];
}
[watchlistDoneBtn setHidden:TRUE];
companyDetailsPushed = YES;
if(viewMode == SearchViewMode)
[companyDetailsViewController setCompany:[searchResults objectAtIndex:indexPath.row]];
else if(viewMode == WatchlistViewMode)
[companyDetailsViewController setCompany:[[[Financial_deAppDelegate sharedAppDelegate] watchlistCompanies] objectAtIndex:indexPath.row]];
[[self navigationController] pushViewController:companyDetailsViewController animated:YES];
}
- (void) bearbeitenAction:(UIButton *) sender {
NSLog(@"Berbeiten btn was pressed");
if(berbeitenViewController == nil){
berbeitenViewController = [[BerbeitenViewController alloc] init];
[berbeitenViewController setup];
}
[self.navigationController pushViewController:berbeitenViewController animated:YES];
}
firstChildViewController = berbeitenViewController in the code:
- (void) setup {
self.navigationItem.hidesBackButton = YES;
}
// Implement loadView to create a view hierarchy programmatically, without using a nib.
- (void)loadView {
NSLog(@"BerbeitenViewController: loadView");
UIView *mainView = [[[UIView alloc] initWithFrame:CGRectMake(0, 0, [[UIScreen mainScreen] applicationFrame].size.width, [[UIScreen mainScreen] applicationFrame].size.height)] autorelease];
[mainView setBackgroundColor:[UIColor darkGrayColor]];
mainView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
mainView.contentMode = UIViewContentModeScaleToFill;
[mainView setAutoresizesSubviews:YES];
berbeitenBackBtn = [[UIButton alloc] initWithFrame:CGRectMake(5, 23, 69, 36)];
[berbeitenBackBtn setBackgroundImage:[UIImage newImageFromResource:@"back_btn.png"] forState:UIControlStateNormal];
[berbeitenBackBtn addTarget:self action:@selector(popViewController:) forControlEvents:UIControlEventTouchUpInside];
[berbeitenBackBtn setEnabled:TRUE];
[self.navigationController.view addSubview:berbeitenBackBtn];
[berbeitenBackBtn release];
berbeitenAddBtn = [[UIButton alloc] initWithFrame:CGRectMake(260, 23, 55, 36)];
[berbeitenAddBtn setBackgroundImage:[UIImage newImageFromResource:@"bearbeiten_add_btn.png"] forState:UIControlStateNormal];
[berbeitenAddBtn addTarget:self action:@selector(addCompany:) forControlEvents:UIControlEventTouchUpInside];
[berbeitenAddBtn setEnabled:TRUE];
[self.navigationController.view addSubview:berbeitenAddBtn];
[berbeitenAddBtn release];
companiesTable = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, [[UIScreen mainScreen] applicationFrame].size.width, 366)];
companiesTable.delegate = self;
companiesTable.dataSource = self;
[mainView addSubview:companiesTable];
[companiesTable release];
self.view = mainView;
}
- (void)viewDidLoad {
NSLog(@"BerbeitenViewController viewDidLoad");
[super viewDidLoad];
self.title = @"Edit watchlist";
}
//MARK: Buttons actions
- (void) popViewController:(UIButton *) sender {
NSLog(@"Pop BerbeitenViewController");
[self.navigationController popViewControllerAnimated:YES];
}
- (void) addCompany:(UIButton *) sender {
NSLog(@"Berbeiten addCompany btn pushed");
if(searchViewController == nil){
searchViewController = [[SearchViewController alloc] init];
[searchViewController setup];
}
[self.navigationController pushViewController:searchViewController animated:YES];
}
secondChildViewController = searchViewController in code
- (void) setup {
self.navigationItem.hidesBackButton = YES;
}
// Implement loadView to create a view hierarchy programmatically, without using a nib.
- (void)loadView {
NSLog(@"BerbeitenViewController: loadView");
UIView *mainView = [[[UIView alloc] initWithFrame:CGRectMake(0, 0, [[UIScreen mainScreen] applicationFrame].size.width, [[UIScreen mainScreen] applicationFrame].size.height)] autorelease];
[mainView setBackgroundColor:[UIColor darkGrayColor]];
mainView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
mainView.contentMode = UIViewContentModeScaleToFill;
[mainView setAutoresizesSubviews:YES];
searchViewBackBtn = [[UIButton alloc] initWithFrame:CGRectMake(5, 23, 69, 36)];
[searchViewBackBtn setBackgroundImage:[UIImage newImageFromResource:@"back_btn.png"] forState:UIControlStateNormal];
[searchViewBackBtn addTarget:self action:@selector(popViewController:) forControlEvents:UIControlEventTouchUpInside];
[searchViewBackBtn setEnabled:TRUE];
[self.navigationController.view addSubview:searchViewBackBtn];
[searchViewBackBtn release];
self.view = mainView;
}
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[super viewDidLoad];
self.title = @"Edit Watchlist";
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
编辑 #2
我查看了你的代码,一切似乎都很好。对我来说唯一不合适的是您向导航控制器添加子视图而不是使用子控制器的 navigationItem。我从来没有见过这样做的。每个 ViewController 都有一个 UINavigationItem 属性当视图控制器被推到导航栏上时,它代表视图控制器。只需通读文档概述即可了解一些背景信息。
该 NavigationItem 有一个标题、左按钮和右按钮,您可以设置...我会尝试将按钮设置为这些属性,因为通过向导航控制器添加子视图,它可能会对标题做一些有趣的事情...再次,我从来没有见过你这样做,所以我不确定它是对还是错。您需要做的唯一更改是将按钮更改为 UIBarButtonItem 类。尝试一下。
原始
根视图控制器位于数组中的索引 0...所以如果您这样做:
它将始终设置根的标题。尝试这样做:
在子控制器的 viewWillAppear 方法中进行这种设置甚至可能更容易......这样您就不必在导航控制器的子级中搜索正确的视图控制器。
希望这有帮助
编辑
您可以尝试仅在 init 方法中设置标题:
这样,您就允许对象的 init 方法负责初始化对象的值(这是一件好事)。
EDIT #2
I looked through your code and everything seems okay. The only thing that looks out of place to me is that you are adding a subview to the navigation controller instead of using the child controller's navigationItem. I have never seen it done this way. Each ViewController has a UINavigationItem property that represents the view controller when it is pushed onto a navigation bar. Just read through the Overview of the documentation for some background.
That NavigationItem has a title, left-button and right-button that you can set... I would try setting your buttons to those properties because by adding subviews to the navigation controller it could be doing something funky with the title... Again, I have never seen it done the way you are doing it so I 'm not really sure if it is right or wrong. The only changes you will have to make is changing the buttons to the UIBarButtonItem class. Give it a try.
Original
The root view controller is at index 0 in the array... so if you doing this:
it will always set the root's title. Try to do it at:
It might even be easier to do this sort of setup in the child controller's viewWillAppear method... that way you don't have to search through the navigation controller's children for the correct view controller.
hope this helps
EDIT
You could try ONLY setting the title in the init method:
This way, you are allowing the object's init method to be in charge of initializing the object's values (which is a good thing).
您应该将
setup
代码移至viewDidLoad
方法。当已经为您设置了导航项时,将调用viewDidLoad
。要设置标题,只需使用
self.title = @"my view";
- 您不应直接在 navigationItem 上设置标题。You should move the
setup
code to theviewDidLoad
method instead. TheviewDidLoad
is called when the navigation item has already been setup for you.To set the title, simply use
self.title = @"my view";
- you should not set the title directly on the navigationItem.问题的根源是我使用此地址 http://sebastiancelis 中找到的方法添加的导航栏的自定义背景图像。 com/ .基本上发生的事情是,我引用作者的话:
当我找到这个改变导航栏背景的解决方案时,我很确定我做对了,但似乎我没有......
再次感谢您的宝贵时间!
the source of the problem was the custom background image for the navigationBar that i added using the method found at this address http://sebastiancelis.com/ . Basically what happened was and i quote from the author:
when i found this solution for changing the background of the navigationBar i was pretty sure that i got it right but it seems i didn't..
thank you again for your time!