I am stuck trying to customize UINavigationController
's backbutton.
In RootViewController I set self.title in viewDidLoad
, and this string appears in Navigation Bar. In -didSelectRowAtIndexPath
I create child view controller, configure back button and call -pushViewController
. Processing for child will push child viewcontrollers onto the stack; I need back button to pop to initial view, just as when going back from first child view controller. Currenty backbutton will pop to prior view, so if there are 5 child view controllers on the stack, I have to hit back button 5 times to get to root view.
I am unable to get action to fire off when back button is displayed. I am able to popToRootViewController
when in child VC; however, backbutton now appears on root view(!) and I have to hit backbutton once more to restore original title and remove backbutton.
Here is part of root -viewDidLoad
:
- (void)viewDidLoad {
self.title = @"My Nav Bar Title"; // displays on root navigation bar title
// some setup code...
[super viewDidLoad];
}
Here is part of -didSelectRowAtIndexPath
, where selecting a tableview cell results in child view being pushed onto stack:
- (void)tableView:(UITableView *)tableView
didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
ChildVC *child = [[ChildVC alloc]
initWithNibName:@"Child"
bundle:nil];
[self.navigationController dismissModalViewControllerAnimated:YES];
[tableView deselectRowAtIndexPath:indexPath animated:YES];
UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithTitle:@"Quiz" style:UIBarButtonItemStylePlain target:self action:@selector(backToMenu)];
self.navigationItem.backBarButtonItem = backButton;
[backButton release];
[self.navigationController pushViewController:child
animated:YES];
[child release];
}
Here is action method which doesn't fire when backbutton is pressed:
-(void)backToMenu {
NSLog(@" in root backToMenu");
[self.navigationController popViewControllerAnimated:YES];
}
ChildVC will also create a new child in its -didSelectRowAtIndexPath
and push the new child controller, as the next child 'page':
- (void)tableView:(UITableView *)tableView
didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
Child *newChild = [[Child alloc]
initWithNibName:@"Child"
bundle:nil];
[self.navigationController dismissModalViewControllerAnimated:YES];
[tableView deselectRowAtIndexPath:indexPath animated:YES];
self.title = self.quizString; // child view correctly displays customized title
开发者_如何学编程UIBarButtonItem *backButton = [[UIBarButtonItem alloc]
initWithTitle:@"Quiz"
style:UIBarButtonItemStylePlain
target:self
action:@selector(backToMenu)];
self.navigationItem.backBarButtonItem = backButton;
[backButton release];
[self.navigationController pushViewController:newQuestion
animated:YES];
[newChild release];
}
In Child -viewWillDisappear
I set a global variable so I known when to push new child and when to pop back to root:
-(void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:YES];
if (startOver) {
[self backToMenu];
}
}
Child -backToMenu:
-(void)backToMenu {
[self.navigationController popToRootViewControllerAnimated:YES];
}
Here is the sequence when back button is pressed in Child:
-- Child -viewWillDisappear
is invoked, calls -backToMenu
-- -backToMenu calls popToRootViewControllerAnimated:
-- Child -viewWillDisappear
is invoked again, calls -backToMenu
-- root -viewWillAppear
is invoked
-- control returns to Child -backToMenu
Root view appears correctly, but Nav bar contains back button and title just like it still was a Child view. Pressing back button removes back button an restores original title.
How can I make this work? Ideally I would like to only have 1 child view on the stack, but I can't figure out how; then the back button would go back to root view. But when I tried this, I got NSInvalidArgumentException
', reason: 'Pushing the same view controller instance more than once is not supported...'
Also, anything obvious why action is not fired when backbutton is pressed? Any help is GREATLY appreciated...thx
UIBarButtonItem *btnBack=[[UIBarButtonItem alloc]initWithTitle:@"" style:UIBarButtonItemStyleDone target:self action:@selector(back:)] ;
self.navigationItem.leftBarButtonItem=btnBack;
//Add image on back button
UIImage *backButtonImage = [[UIImage imageNamed:@"btn_back.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 13, 0, 6)];
[btnBack setBackgroundImage:backButtonImage forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
put this code in your view controller[initWithNibName method]
form where you want to pop at root view controller
- (void) back : (id)sender
{
[self.navigationController popToRootViewControllerAnimated:YES];
}
uhm, your backButton calls popToRootViewController
, which calls viewWillDissapear
, which, if startOver is true calls popToRootViewController
AGAIN?
what happens if it's false anyway? it continues the popToRootViewController
called earlier ...
backButton->popToRoot->viewWillDissapear->check startOver
->YES->popToRoot->viewWillDissapear again->check startOver again->??
->NO->continue the disappearing of the view that was called also by popToRoot
isn't that if there redundant, since both it's branches continue previously popToRoot
or call popToRoot
again?
why not test for startOver first(in your backToMenu), then popToRootViewController
if true?
精彩评论