UINavigationController popToRootViewController不重置Title,清除后退按钮

时间:2011-05-12 11:33:47

标签: uinavigationcontroller uinavigationbar uibarbuttonitem

我很难尝试自定义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

2 个答案:

答案 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];

}