【问题标题】:is there a way to have a button persist throughout UINavigationController stack?有没有办法让按钮在整个 UINavigationController 堆栈中保持不变?
【发布时间】:2012-03-04 21:48:38
【问题描述】:

我知道如何为我推入导航控制器堆栈的每个控制器添加一个按钮。 但是我需要始终在导航栏的右上角有一个设置按钮,无论哪个控制器被按下或弹出。该按钮应以模态方式显示设置视图控制器。

对我来说,让每个控制器的 viewDidLoad 都包含按钮代码以及设置控制器标题似乎是一种 hack。

似乎我应该能够从导航控制器本身插入此按钮,指向导航控制器中的选择器。然后,此方法将通过此时恰好在堆栈中处于活动状态的任何控制器以模态方式呈现 settingsController。

关于如何实现这一点的任何想法?

【问题讨论】:

    标签: ios cocoa-touch uinavigationcontroller


    【解决方案1】:

    好的,这就是我所做的:

    1 - 子类 UINavigationController 并包含我的设置控制器的标题

    2 - 覆盖 -pushViewController:aniamted:

    - (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated
    {
        [super pushViewController:viewController animated:animated];
        UIBarButtonItem *settingsButton = [[UIBarButtonItem alloc]initWithTitle:@"Settings" 
                                                                          style:UIBarButtonItemStylePlain 
                                                                         target:self
                                                                         action:@selector(shouldPresentSettingsView)];
        [viewController.navigationItem setRightBarButtonItem: settingsButton];
        [settingsButton release];
    }
    

    3 - 添加两个方法:

    - (void)shouldPresentSettingsView
    {
        SetupViewController *settingsView = [[SetupViewController alloc] init];
        UINavigationController *tempController = [[UINavigationController alloc]initWithRootViewController:settingsView];
        UIBarButtonItem *cancelButton = [[UIBarButtonItem alloc] initWithTitle:@"Back" 
                                                                         style:UIBarButtonItemStylePlain 
                                                                        target:self 
                                                                        action:@selector(shouldDismissSettingsView)];
        settingsView.navigationItem.leftBarButtonItem = cancelButton;
        [self.visibleViewController presentModalViewController:tempController animated:YES];
    
        [cancelButton release];
        [settingsView release];
        [tempController release];
    }
    
    - (void)shouldDismissSettingsView
    {
        [self dismissModalViewControllerAnimated:YES];
    }
    

    【讨论】:

      【解决方案2】:

      将导航控制器的委托设置为全局对象,例如应用委托。在该对象中,初始化 UIBarButtonItem 并保存到实例变量:

      - (void)setupSettingsButton
      {
          settingsBarButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCompose 
                                                                            target:self 
                                                                            action:@selector(openSettings)];
      }
      

      然后在推送前配置每个视图控制器的navigationItem:

      - (void)navigationController:(UINavigationController *)aNavigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
      {
          viewController.navigationItem.rightBarButtonItem = settingsBarButton;
      }
      

      并处理按钮操作...

      - (void)openSettings
      {
          [navigationController presentViewController:settingsVC animated:YES completion:NULL];
      }
      

      【讨论】:

      • 感谢您的想法。不过,与此同时,我最终提出了另一种方法(请参阅我的答案),从设计的角度来看,我认为这可能更合适,因为它将新行为限制在导航控制器中。但是,是的,我的意思是......从概念上讲,我明白你的意思,也可以说这是一项“委托”任务。
      • 是的,我明白了。我通常更喜欢委托和组合而不是继承,但我认为在这种情况下,无论如何我们都处于不稳定的设计基础上,因为我们正在从该视图控制器代码之外修改推送视图控制器的 navigationItem。最正确的方法可能是拥有一个始终显示此按钮的 UIViewController 的子类。但无论如何,它在这一点上分裂了头发。很高兴你成功了。
      • 我可能错了,但我想我之前确实听说过 ViewControllers 确实不应该修改自己的导航项。我猜的想法是,在一个完美的世界中,视图控制器甚至不知道它可能存在于导航控制器的上下文中。所以要么是“推杆”(这里的新术语......只是组成了推杆和推杆的概念:p)在推杆之前设置推杆的导航项,或者更好的是(至少在我看来),甚至不是推杆控制器应该知道如何配置下一个控制器。
      • 我不知道。至少在这种情况下,我认为我提出的解决方案在设计方面是最有意义的:不同的控制器只知道它们的存在和构造是孤立的,而不管任何容器。导航控制器子类是导航控制器的一个特化,它增加了普通导航控制器如何通过提供整个模态功能来修改主机控制器的上下文。但是,再次感谢您的想法。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-19
      • 2019-11-27
      • 2011-02-11
      • 1970-01-01
      • 2011-07-05
      相关资源
      最近更新 更多