下面的代码隐藏并显示了导航栏。它在第一个视图加载时被隐藏,然后在“子”被调用时被隐藏。问题是,当他们回到根视图....时,我找不到触发它再次隐藏的事件/动作

我在根页面上有一个“测试”按钮,手动执行操作,但它并不漂亮,我希望它是自动的。

-(void)hideBar 
{
    self.navController.navigationBarHidden = YES;
}
-(void)showBar 
{       
    self.navController.navigationBarHidden = NO;
}

当前回答

我不得不对其他答案做出的一个轻微调整是,只有在viewWillDisappear中取消隐藏条,如果它消失的原因是由于导航项被推到它上面。这是因为视图可能因其他原因而消失。

所以我只在这个视图不再是最顶层视图时才取消隐藏条:

- (void) viewWillDisappear:(BOOL)animated
{
    if (self.navigationController.topViewController != self)
    {
        [self.navigationController setNavigationBarHidden:NO animated:animated];
    }

    [super viewWillDisappear:animated];
}

其他回答

我将把代码放在viewWillAppear委托中显示每个视图:

就像你需要隐藏它的地方:

- (void)viewWillAppear:(BOOL)animated
{
        [yourObject hideBar];
}

就像这样,你需要展示它:

- (void)viewWillAppear:(BOOL)animated
{
        [yourObject showBar];
}

如果你想把导航栏完全隐藏在控制器中,一个更干净的解决方案是,在根控制器中,有这样的东西:

@implementation MainViewController
- (void)viewDidLoad {
    self.navigationController.navigationBarHidden=YES;
    //...extra code on view load  
}

当你在控制器中推送子视图时,导航栏将保持隐藏状态;如果你想只在子对象中显示它,你将在viewWillAppear回调中添加用于显示它的代码(self.navigationController.navigationBarHidden=NO;),类似地,在viewWillDisappear中隐藏它的代码

我相信@chad-m的回答。

以下是Swift版本:

创建一个新文件MyNavigationController.swift


import UIKit

class MyNavigationController: UINavigationController, UINavigationControllerDelegate {

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
        self.delegate = self
    }

    func navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool) {
        if viewController == self.viewControllers.first {
            self.setNavigationBarHidden(true, animated: animated)
        } else {
            self.setNavigationBarHidden(false, animated: animated)
        }
    }

}

在StoryBoard中将UINavigationController的类设置为MyNavigationController 就是这样!

chad-m的回答和我的不同之处在于:

继承自UINavigationController,所以你不会污染你的rootViewController。 使用self.viewControllers.first而不是homeViewController,这样你就不会为你的100个UINavigationControllers在一个StoryBoard中做100次。

最简单的实现可能是让每个视图控制器在viewWillAppear:animated:方法中指定它的导航栏是否隐藏。同样的方法也适用于隐藏/显示工具栏:

- (void)viewWillAppear:(BOOL)animated {
    [self.navigationController setToolbarHidden:YES/NO animated:animated];
    [super viewWillAppear:animated];
}

如果有人仍然对@fabb在接受的答案中评论的快速反滑取消错误有问题。

我设法通过覆盖viewDidLayoutSubviews来修复这个问题,除了viewWillAppear/viewWillDisappear,如下所示:

override func viewWillAppear(animated: Bool) {
    super.viewWillAppear(animated)
    self.navigationController?.setNavigationBarHidden(false, animated: animated)
}

override func viewWillDisappear(animated: Bool) {
    super.viewWillDisappear(animated)
    self.navigationController?.setNavigationBarHidden(true, animated: animated)
}

//*** This is required to fix navigation bar forever disappear on fast backswipe bug.
override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    self.navigationController?.setNavigationBarHidden(false, animated: false)
}

在我的例子中,我注意到这是因为根视图控制器(其中nav是隐藏的)和被推的视图控制器(nav是显示的)有不同的状态栏风格(例如暗和亮)。当你开始向后滑动以弹出视图控制器时,会有额外的状态栏颜色动画。如果你为了取消交互式弹出而松开手指,而状态栏动画还没有完成,导航栏就永远消失了!

但是,如果两个视图控制器的状态栏样式相同,则不会出现此错误。