【问题标题】:How to show back button on the RootViewController of the UINavigationController?如何在 UINavigationController 的 RootViewController 上显示返回按钮?
【发布时间】:2012-07-02 06:00:20
【问题描述】:

这是我的代码。我想在打开的 rootviewController 上放一个后退按钮。

- (void)selectSurah:(id)sender {

    SurahTableViewController * surahTableViewController = [[SurahTableViewController alloc] initWithNibName:@"SurahTableViewController" bundle:nil];
    surahTableViewController.navigationItem.title=@"Surah";

    surahTableViewController.navigationItem.backBarButtonItem.title=@"Back";

    UINavigationController *aNavigationController = [[UINavigationController alloc] initWithRootViewController:surahTableViewController];

    [self presentModalViewController:aNavigationController animated:YES];   
}

【问题讨论】:

  • 答案显而易见。返回调用 presentModalViewController 的位置。请参阅下面的@Flex_Addicted 答案。

标签: iphone ios xcode uinavigationcontroller uibarbuttonitem


【解决方案1】:

对于 Swift,请尝试以下方法:

override func viewDidLoad() {
    super.viewDidLoad();
    self.navigationItem.hidesBackButton = true;
    let backButton = UIBarButtonItem(
        image: UIImage(named: "my_back_asset"), style: .plain,
        target: self, action: #selector(self.onBack));
    self.navigationItem.leftBarButtonItem = backButton;
}

@objc private func onBack() {
    let controller = self.navigationController?.popViewController(animated: true);
    if controller == nil {
        // Handle pressing back when on root here.
    }
}

注意将“my_back_asset”更改为您自己的后退按钮图像。

【讨论】:

    【解决方案2】:

    这就是我认为每个人都在寻找的答案。

    只需在自定义初始化程序中提供一个空的 UIViewController 作为 UINavigationController 子类的 rootViewController。然后在呈现之前推送您的实际 rootViewController 而不使用动画:

    init(backButtonRootViewController: UIViewController) {
        super.init(rootViewController: UIViewController())
        
        interactivePopGestureRecognizer?.isEnabled = false
        pushViewController(backButtonRootViewController, animated: false)
    }
    

    您还需要禁用 interactivePopGestureRecognizer 以防止用户滑回空的 rootViewController。

    然后扩展您的子类以实现 UINavigationBarDelegate 的 shouldPop 方法,并在 rootViewController 上按下后退按钮时关闭导航控制器:

    func navigationBar(_ navigationBar: UINavigationBar, shouldPop item: UINavigationItem) -> Bool {
        
        if children.count >= 2 && children[1] == topViewController {
            presentingViewController?.dismiss(animated: true, completion: nil)
            return false
        } else {
            return true
        }
    }
    

    像魅力一样工作!

    【讨论】:

      【解决方案3】:

      我认为不可能将根视图控制器从导航堆栈中弹出,但您可以通过添加 UIButton 作为 UIBarButtonItem 的自定义视图来伪造它:

      UIButton *b = [[UIButton alloc]initWithButtonType:UIButtonTypeCustom];
      [b setImage:[UIImage imageNamed:@"BackImage.png"] forState:UIControlStateNormal];
      [b addTarget:self action:@selector(back:) forControlEvents:UIControlEventTouchUpInside];
      self.leftBarButtonItem = [[UIBarButtonItem alloc]initWithCustomView:b];
      

      可以在here找到合适的iOS UI元素PSD。

      【讨论】:

      • 实现这一点的更短的方法是 - ` self.leftBarButtonItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"BackImage.png"] style:UIBarButtonItemStylePlain target:self action:@selector( showPopup:)] `
      【解决方案4】:

      由于SurahTableViewController 是导航控制器中的根视图控制器,因此您无法返回根视图,因为您已经在那里了。由于您已从其他方式以模态方式呈现它,因此您需要在导航栏上放置一个按钮,该按钮具有 IBAction 调用:

      [self dismissModalViewControllerAnimated:YES];
      

      【讨论】:

        【解决方案5】:

        飞赞,

        Helium3 评论很有道理。

        我想您的按钮需要关闭以模态方式呈现的控制器,这是真的吗?如果我错了,请纠正。

        如果是这样,您可以只创建一个新的UIBarButtonItem 并为UINavigationController 设置一个左(或右)按钮navigationItem。为了不破坏封装,请在 viewDidLoad 方法中为您的 SurahTableViewController 控制器创建它。

        - (void)viewDidLoad
        {
            [super viewDidLoad];
        
            // make attention to memory leak if you don't use ARC!!!
            self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Close"
                   style:UIBarButtonItemStyleBordered
                     target:self
                     action:@selector(close:)];
        }
        
        -(void)close:(id)sender
        {
            // to dismiss use dismissViewControllerAnimated:(BOOL)flag completion:(void (^)(void))completion
            // dismissModalViewControllerAnimated: is deprecated
        
            [self dismissViewControllerAnimated:YES completion:^{ NSLog(@"controller dismissed"); }];
        }
        

        【讨论】:

        • 很抱歉复活死者(线程),但请注意:您应该将按钮添加到 UINavigationController 中呈现的 UIViewController,而不是 UINavigationController 本身!这让我浪费了一个小时左右:(
        • @MadD 抱歉耽搁了。你的意思是?该按钮附加到导航栏。为什么它对你不起作用?提前致谢。
        【解决方案6】:

        UINavigationController 中后退按钮的外观和行为依赖于 UINavigationController 堆栈之间的交互。在第一个控制器上放置一个后退按钮打破了这个约定,没有什么可返回的,这就是你的代码不起作用的原因。

        您需要手动将 UIBarButtonItem 添加到标题栏代码,如:

        self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Back" style:UIBarButtonItemStylePlain target:self action:@selector(back:)];
        

        如果您真的希望它看起来像一个后退按钮,您需要手动创建 UIBarButtonItem 并使用镜像后退按钮的图像。

        不过,另一个建议是,由于您似乎正在尝试使用后退按钮来关闭模态视图控制器,我会坚持使用更传统的东西,例如“关闭”或“完成”按钮来关闭模态视图控制器.后退按钮确实更适合在 UINavigationController 堆栈中导航。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2010-11-30
          • 1970-01-01
          • 2016-07-03
          • 1970-01-01
          • 2023-03-26
          • 2011-03-20
          • 1970-01-01
          相关资源
          最近更新 更多