我很难尝试自定义UINavigationController
的后退按钮。
在RootViewController中,我在viewDidLoad
中设置了self.title,此字符串出现在导航栏中。在-didSelectRowAtIndexPath
我创建子视图控制器,配置后退按钮并调用-pushViewController
。处理子进程将子视图控制器推入堆栈;我需要后退按钮弹出到初始视图,就像从第一个子视图控制器返回时一样。 Currenty后退按钮将弹出到前一个视图,因此如果堆栈上有5个子视图控制器,我必须按回5次按钮才能进入根视图。
显示后退按钮时,我无法启动操作。在孩子VC中我能够popToRootViewController
;但是,后退按钮现在出现在根视图(!)上,我必须再次点击后退按钮以恢复原始标题并删除后退按钮。
以下是根-viewDidLoad
的一部分:
- (void)viewDidLoad {
self.title = @"My Nav Bar Title"; // displays on root navigation bar title
// some setup code...
[super viewDidLoad];
}
以下是-didSelectRowAtIndexPath
的一部分,其中选择tableview单元格会导致子视图被压入堆栈:
- (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];
}
这是按下后退按钮时不会触发的动作方法:
-(void)backToMenu {
NSLog(@" in root backToMenu");
[self.navigationController popViewControllerAnimated:YES];
}
ChildVC还将在其-didSelectRowAtIndexPath
中创建一个新子项,并将新子控制器作为下一个子页'推送':
- (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];
}
在Child -viewWillDisappear
中我设置了一个全局变量,因此我知道何时推送新子项以及何时弹回root:
-(void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:YES];
if (startOver) {
[self backToMenu];
}
}
Child -backToMenu:
-(void)backToMenu {
[self.navigationController popToRootViewControllerAnimated:YES];
}
以下是在Child中按下后退按钮时的顺序:
- 调用子-viewWillDisappear
,调用-backToMenu
- -backToMenu调用popToRootViewControllerAnimated:
- 再次调用子-viewWillDisappear
,调用-backToMenu
- 调用root -viewWillAppear
- 控制返回Child -backToMenu
根视图显示正确,但导航栏包含后退按钮和标题,就像它仍然是子视图一样。按后退按钮可删除后退按钮并恢复原始标题。
我该如何使这项工作?理想情况下,我想在堆栈上只有1个子视图,但我无法弄清楚如何;然后后退按钮将返回到根视图。但是当我尝试这个时,我得到NSInvalidArgumentException
',原因是:“不支持多次推送相同的视图控制器实例......”
此外,当按下后退按钮时,为什么不触发动作的任何明显的原因?任何帮助都非常感谢... thx
答案 0 :(得分:0)
嗯,你的backButton调用popToRootViewController
,调用viewWillDissapear
,如果startOver为true,则调用popToRootViewController
AGAIN?
如果它是假的,会发生什么?它继续前面提到的popToRootViewController
...
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
如果有多余的话,那是不是因为它的分支都在之前继续popToRoot
或再次呼叫popToRoot
?
为什么不首先测试startOver(在backToMenu中),然后popToRootViewController
如果为真?
答案 1 :(得分:0)
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];
将此代码放在您希望弹出 root view controller
的视图控制器[initWithNibName method]
表单中
- (void) back : (id)sender
{
[self.navigationController popToRootViewControllerAnimated:YES];
}