2

The default behaviour when pushing a UIViewController on a UINavigationController is for the OS to display a back button that pops the UIViewController off again.

I have the desire to set a different behavior for this back button (to go back two screens) - is there anyway I can do this without having to create my own back button with custom graphic etc.

Thanks :)

adam
  • 22,404
  • 20
  • 87
  • 119

5 Answers5

4

As I half suspected originally, this isn't possible any exceptionally easy way. So same method applies when creating any custom UIBarButtonItem, just have to source the back button icon from Google....

UIButton *backButtonInternal = [[UIButton alloc] initWithFrame:CGRectMake(0,0,54,30)];
[backButtonInternal setBackgroundImage:[UIImage imageNamed:@"backButton.png"] forState:UIControlStateNormal];
boldSystemFontOfSize:12]];
[backButtonInternal addTarget:self action:@selector(backButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem *backBarButton = [[UIBarButtonItem alloc] initWithCustomView:backButtonInternal];   
[backButtonInternal release];
[[self navigationItem] setLeftBarButtonItem:backBarButton];
[backBarButton release];
adam
  • 22,404
  • 20
  • 87
  • 119
2

Using the "leftBarButtonItem" allows you to set the target and selector. But if you set the "backBarButtonItem" on the previous controller, the target and selector will be ignored. However, the leftBarButtonItem does not have the left pointing arrow.

gstroup
  • 1,064
  • 8
  • 16
0

If you subclass your navigation controller, you can implement the popViewControllerAnimated: method, and throw an isKindOfClass: check in there to determine if the view controller you're looking for is being popped. Eg:

- (UIViewController *)popViewControllerAnimated:(BOOL)animated
{
    //Reference current controller being displayed
    UIViewController *currentController = [self.viewControllers lastObject];

    //Check class
    if ([currentController isKindOfClass:[MyDesiredController class]]) {
        NSLog(@"Popping Desired Controller, Do Stuff Here");
    }

    return [super popViewControllerAnimated:animated];
}

However this does not cancel the actual popping of the view controller (returning nil will stop the controller from popping but will still cause the navigation bar to pop it's information, and returning NO to the shouldPop: delegate method of the navigation bar will still pop the controller regardless. I have heard that this only occurs when using a Navigation Controller, but I haven't tested this).

For your situation however, since you desire to pop two view controllers back, you could possibly remove the second last view controller from the navigation controller's viewcontrollers property by converting the viewcontrollers to an nsmutablearray, removing the controller, and then converting this nsmutablearray back to an array and setting it as the navigation controller's viewcontrollers property. I haven't tested this but I thought I would share the idea.

Adam Eisfeld
  • 1,424
  • 2
  • 13
  • 25
0

Anything wrong with UIViewController's navigationItem property? Here's how I get a cancel button, for example:

self.navigationItem.leftBarButtonItem =
  [[[UIBarButtonItem alloc] initWithBarButtonSystemItem: UIBarButtonSystemItemCancel
                                               target: self
                                               action: @selector(cancel)] autorelease];  
jamie
  • 2,963
  • 1
  • 26
  • 27
0

In parent's viewcontroller,

- (void)viewDidLoad
{    
    self.navigationController.delegate= self;
}

- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
    if (viewController == self)
    {
        // your codes
    }
}
Andy Obusek
  • 12,614
  • 4
  • 41
  • 62
conrkim
  • 11
  • 1