NavigationItem setTitle not working for second level UIViewController

in my application, I have a UITabBarController with a UINavigationControllers initialized as follows

UINavigationController *newsNavigationController = [[UINavigationController alloc] initWithRootViewController: newsViewControler]; 

newsViewController is a UIViewController. When I click a button on a tab to display a navigation item using newsViewController, the title in the navigation bar is set in order. in newsViewController, I have a method that I call after init. In the installation method, I set the title like this [[self navigationItem] setTitle:[category_c title]];

The problem is now, in my newsViewController I have a tableView, when I touch the cell, I want to click on the UIViewController with the selected news and in the navigation bar to show the name.

In the UIViewController, I have the same installation method in which I configure the header as described above. The problem is that it is not shown. The navigation item is not null because I can call self.navigationItem.hidesBackButton = YES; , and it hides the stand every time, but the title is not displayed.

I create and push the UIViewController news, like this, when the touch of the camera touched

 if(newsViewController == nil){ newsViewController = [[NewsViewController alloc] init]; [newsViewController setup]; } [self.navigationController pushViewController: newsViewController animated:YES]; 

The setup method in newsViewController is as follows:

 - (void) setup { self.navigationItem.hidesBackButton = YES; [self.navigationItem setTitle:@"my view"]; } 

in newsViewController I have viewDidLoad and tried to set the title there, but without 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 containing the UITableView gets the myTitle header instead of the newsViewController that I clicked when I touched the cell.

any pointers? I do not understand why the header is set incorrectly.

EDIT2: after reading a bit more and going through my code with the debugger step by step and comparing the rootviewcontrollers with childViewControllers, I noticed that the navigationItem element is created in the viewDidLoad method of childViewController after setting self.title = @ "title", so this is not a zero situation. In the debugger, when I expand the _navigationItem variable, the _navigationBar field is zero after exiting viewDidLoad, in the rootViewControllers navigationBar NOT NULL, and there is a title. I read that if navigationBar is null, the title will not be displayed. In the image, this is what I saw in the debugger. alt text http://img138.imageshack.us/img138/1513/picture2bq.png now I'm looking in this direction.

EDIT1: Below is the code for parental control, firstChildViewController and second ChildViewController. parental control is considered (title is in order). I press a button on the navigation bar that calls bearbeitenAction -> the first child is pressed (the title does not appear). In the firstChildViewController navigation bar, I have a button that, when clicked, pushes the new ViewController on the stack (secondChildViewController). The title of the second ChildViewController does not fit. When I click Back, the firstChildViewController header displays 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 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"; } 
+4
source share
3 answers

The source of the problem was the custom background image for the navigationBar, which I added using the method found at this address http://sebastiancelis.com/ . Basically what happened, and I quote the author:

Using a category, we could easily add our own setBackgroundImage: method and call it whenever we create a UINavigationBar or UINavigationController. This method will simply add a UIImageView as go to the navigation bar and then send this sub-item to the background of SuperView.

However, if you try this, you will quickly see that it just works. UIImageView is definitely visible and even initially on the correct z-index. However, as soon as you click or place the view controller on the navigation controller stack, you will see that the background image is no longer in the background. Instead, it blocks the title and navigation of the buttons. This is definitely not what we want.

when I found this solution to change the background of the navigation bar, I was sure that I did it, but it seems that I did not.

Thanks again for your time!

0
source

EDIT No. 2

I looked through your code and everything looks good. The only thing that looks out of place for me is that you add a subview to the navigation controller, instead of using the child controller navigation element. I have never seen this done so. Each ViewController has a UINavigationItem property, which is a view controller when it is clicked on the navigation bar. Just read the documentation review for some background.

That the NavigationItem has a title, a left button and a right button that you can set ... I would try setting your buttons to these properties, because by adding subviews to the navigation controller, it could do something funky with heading ... Again, I never saw this being done the way you do it, so I'm not sure if this is correct or not. The only changes you have to make are to change the buttons to the UIBarButtonItem class. Give it a try.

Original

The root view controller has index 0 in the array ... so if you do this:

 [[self.navigationController.viewControllers objectAtIndex:0] setTitle:@"myTitle"] 

it will always set the root title. Try to do this at:

 objectAtIndex:([self.navigationController.viewControllers count] - 1) 

It might be easier to make such a setting in the viewLillAppear method for the child controller ... so you don’t have to look for children of the navigation controller for the correct view controller.

hope this helps

EDIT You can try ONLY setting the header in the init method:

 -(id)init { if (self = [super init]) { self.title = @"My Title"; } return self; } 

Thus, you allow the init init method of the object to initialize the values ​​of the object (which is good).

+2
source

Instead, you should move the setup code to the viewDidLoad method. viewDidLoad is called when the navigation item is already configured for you.

To set the title, simply use self.title = @"my view"; - You should not specify the title directly in the navigationItem file.

+1
source

Source: https://habr.com/ru/post/1301338/


All Articles