5

I have a category that extends the functionality of a UIViewController that adds its own subtitle to the title bar. It needs to know what buttons are present in the title bar so that it can resize the labels within. I can detect if there is a leftBarButtonItem and rightBarButtonItem, but when it comes to a backBarButtonItem everything I have tried tells me that there is no back button, when in fact there is one when the view loads. This is what I've used to test:

if(self.parentViewController.navigationItem.backBarButtonItem == nil){
    NSLog(@"no back button");
}
else {
    NSLog(@"has back button");
}

if(self.parentViewController.navigationController.navigationItem.backBarButtonItem == nil){
    NSLog(@"1no back button");
}
else {
    NSLog(@"1has back button");
}

if(self.navigationItem.backBarButtonItem == nil){
    NSLog(@"2no back button");
}
else {
    NSLog(@"2has back button");
}

if(self.navigationController.navigationItem.backBarButtonItem == nil){
    NSLog(@"3no back button");
}
else {
    NSLog(@"3has back button");
}

if(self.presentingViewController.navigationItem.backBarButtonItem == nil){
    NSLog(@"4no back button");
}
else {
    NSLog(@"4has back button");
}

if(self.presentingViewController.navigationController.navigationItem.backBarButtonItem == nil){
    NSLog(@"5no back button");
}
else {
    NSLog(@"5has back button");
}

if(self.presentedViewController.navigationItem.backBarButtonItem == nil){
    NSLog(@"6no back button");
}
else {
    NSLog(@"6has back button");
}

if(self.presentedViewController.navigationController.navigationItem.backBarButtonItem == nil){
    NSLog(@"7no back button");
}
else {
    NSLog(@"7has back button");
}

I've tried putting this in viewDidLoad, viewWillAppear and viewDidAppear, and they all return that there is no back button. In the previous view I do set the back button manually using self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc]initWithTitle:@"Back" style:UIBarButtonItemStyleBordered target:nil action:nil]; (The back button has to say back instead of the previous views title). Logically to me this means that the self.parentViewController is the one that should tell me if there is a back button on this view but clearly it doesn't.

Fonix
  • 11,447
  • 3
  • 45
  • 74
  • Could you just check for subviews for a button with the word back? – propstm Dec 10 '12 at 13:21
  • @propstm maybe, but I would like to keep it as generic as possible, back button may not have the word back in it – Fonix Dec 10 '12 at 13:23
  • I had a similiar question once but phrased it slightly different. However, the answers were quite helpful to me. Might help you as well. http://stackoverflow.com/questions/8235261/how-to-determine-if-a-viewcontroller-is-top-level-or-not However, none of the solutions literally checks the UI item itself. – Hermann Klecker Dec 10 '12 at 15:28

1 Answers1

1

If current scenario is true and you are expecting back buttons to say "back" you can traverse subviews looking for that button.

BOOL exists = NO;
for (UIView *view in [self.view subviews]) {
    if ([view isMemberOfClass [UIButton class]]) {
        if([view.title isEqualToString: @"Back"]){
                exists = YES;
        }
    }
}
if(!exists){
     //Add back button
}

enter image description here

propstm
  • 3,461
  • 5
  • 28
  • 41
  • If push comes to shove this may work, but I would like to keep it generic for when the back button doesnt have the word back in it. – Fonix Dec 10 '12 at 13:29
  • Just for kicks can you log self.navigationController, or self.presentedViewController.navigationController. I just want to make sure we aren't running into an issue where that value is nil – propstm Dec 10 '12 at 13:31
  • I just put your code in and the second scenario works for me. Will edit my response with screenshot. – propstm Dec 10 '12 at 13:36
  • ok, i just logged them, the self.navigationController is not nil, but the self.presentedViewController.navigationController is nil it seems – Fonix Dec 10 '12 at 13:37
  • hmm ok, that is one step closer, but the thing is the previous view sets the current views back button (didnt seem to work any other way, otherwise it still displayed the title in the back button instead of back) so you would need to test it coming from a previous view – Fonix Dec 10 '12 at 13:39