iPhone仅在第一页上隐藏导航栏

Lee*_*ong 374 hide uinavigationcontroller ios

我有下面的代码隐藏并显示导航栏.它在第一个视图加载时隐藏,然后在调用"children"时隐藏.麻烦的是,当他们回到根视图时,我找不到触发它再次隐藏的事件/动作....

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

-(void)hideBar 
{
    self.navController.navigationBarHidden = YES;
}
-(void)showBar 
{       
    self.navController.navigationBarHidden = NO;
}
Run Code Online (Sandbox Code Playgroud)

Ala*_*ers 1015

我发现最好的解决方案是在第一个视图控制器中执行以下操作.

Objective-C的

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

- (void)viewWillDisappear:(BOOL)animated {
    [self.navigationController setNavigationBarHidden:NO animated:animated];
    [super viewWillDisappear:animated];
}
Run Code Online (Sandbox Code Playgroud)

迅速

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

override func viewWillDisappear(animated: Bool) {
    self.navigationController?.setNavigationBarHidden(false, animated: animated)
    super.viewWillDisappear(animated)
} 
Run Code Online (Sandbox Code Playgroud)

这将导致导航栏从左边(下一个视图一起),动画,当你推下一个UIViewController堆栈上,和(同旧观点一起)动画至左侧,当你按后退按钮UINavigationBar.

请注意,这些不是委托方法,您要覆盖UIViewController这些方法的实现,并且根据文档,您必须在实现中的某处调用super的实现.

  • **警告:**执行快速反向扫描时,这会产生一个非常糟糕的错误.假设A(无导航栏)和B(带导航栏)被推入堆栈.当在视图B上并进行快速反向扫描,但是足够早地释放以保持在B时,导航栏仍然被隐藏.现在再也没有办法回去了.这是由于`animated = YES`.我知道`animated = NO`看起来很难看,但是当隐藏导航栏的动画还没有完成时,似乎忽略了再次显示它的动画.还没有解决方案. (26认同)
  • 问题在2010年得到解答,并在2015年底帮助我!谢谢. (7认同)
  • 在Swift中:覆盖func viewWillAppear(动画:Bool){self.navigationController?.setNavigationBarHidden(true,animated:true)super.viewWillAppear(true)}覆盖func viewWillDisappear(动画:Bool){self.navigationController?.setNavigationBarHidden(false, animated:false)super.viewWillDisappear(true)} (3认同)
  • 这完全是摇滚!我已经为此奋斗了至少一天。谢谢!!! (2认同)

小智 54

我找到的另一种方法是为以下方面设置委托NavigationController:

navigationController.delegate = self;
Run Code Online (Sandbox Code Playgroud)

并使用setNavigationBarHiddennavigationController:willShowViewController:animated:

- (void)navigationController:(UINavigationController *)navigationController 
      willShowViewController:(UIViewController *)viewController 
                    animated:(BOOL)animated 
{   
    // Hide the nav bar if going home.
    BOOL hide = viewController != homeViewController;
    [navigationController setNavigationBarHidden:hide animated:animated];
}
Run Code Online (Sandbox Code Playgroud)

ViewController在一个地方轻松自定义每个人的行为.

  • 我认为这是最好的答案.这很完美. (6认同)
  • 完美的解决方案。这应该是公认的答案。谢谢! (2认同)
  • 完美的答案。如果我们无法重写第一个视图控制器上的 viewWillAppear 和 viewWillDisappear 方法,它也适用。 (2认同)
  • 惊人的。选择的答案可以正常工作,但仅适用于简单的应用程序。当导航栏位于选项卡控制器中并以各种方式推送/呈现各种 VC 时,此答案有效。 (2认同)

小智 17

我必须对其他答案进行一些轻微的调整,只是取消隐藏在viewWillDisappear中的栏,如果它消失的原因是由于推送它的导航项目.这是因为视图可能因其他原因而消失.

所以如果这个视图不再是最顶层的视图,我只会取消隐藏栏:

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

    [super viewWillDisappear:animated];
}
Run Code Online (Sandbox Code Playgroud)

  • +1,你_usually_不想在按下模态对话框时显示导航栏. (3认同)

Pab*_*ruz 16

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

像这样你需要隐藏它:

- (void)viewWillAppear:(BOOL)animated
{
        [yourObject hideBar];
}
Run Code Online (Sandbox Code Playgroud)

像这样你需要展示它:

- (void)viewWillAppear:(BOOL)animated
{
        [yourObject showBar];
}
Run Code Online (Sandbox Code Playgroud)

  • 唯一的问题是当您从一个视图导航到下一个视图时,导航栏会"弹出"并进入视图.是否可以让导航栏不在第一个视图上,当第二个视图滑入到位时,它有导航栏,没有任何弹出? (2认同)
  • @henning要使NavBar幻灯片进/出如您所期望的那样,您需要使用setNavigationBarHidden:animated:.请参阅下面的Alan Rogers的答案(应该将其标记为"解决方案"). (2认同)
  • 这个答案有些错误(viewWill/DidAppear)应该调用super.另请参阅下面的答案,找到一个解决方案,您无需将其添加到每个视图控制器. (2认同)

hun*_*ros 14

当前接受的答案与问题中描述的预期行为不匹配.该问题要求导航栏隐藏在根视图控制器上,但在其他任何地方都可见,但接受的答案会隐藏特定视图控制器上的导航栏.当第一个视图控制器的另一个实例被推入堆栈时会发生什么?即使我们没有查看根视图控制器,它也会隐藏导航栏.

相反,@ Chad M.的使用策略UINavigationControllerDelegate是一个很好的策略,这是一个更完整的解决方案.脚步:

  1. 子类 UINavigationController
  2. 实现-navigationController:willShowViewController:animated方法以显示或隐藏导航栏是否显示根视图控制器
  3. 重写初始化方法以将UINavigationController子类设置为其自己的委托

此解决方案的完整代码可在此Gist中找到.这是navigationController:willShowViewController:animated实施:

- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
    /* Hide navigation bar if root controller */
    if ([viewController isEqual:[self.viewControllers firstObject]]) {
        [self setNavigationBarHidden:YES animated:animated];
    } else {
        [self setNavigationBarHidden:NO animated:animated];
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 这是一个比接受的答案更合适的答案 (2认同)

Eug*_*ets 14

在Swift 3中:

override func viewWillAppear(_ animated: Bool) {
    navigationController?.navigationBar.isHidden = true
    super.viewWillAppear(animated)
}


override func viewWillDisappear(_ animated: Bool) {
    if (navigationController?.topViewController != self) {
        navigationController?.navigationBar.isHidden = false
    }
    super.viewWillDisappear(animated)
}
Run Code Online (Sandbox Code Playgroud)

  • @Kitson,检查user486646的答案:_我必须在其他答案上做一个轻微的调整,只是取消隐藏在viewWillDisappear中的栏,如果它消失的原因是由于推送它的导航项目.这是因为视图可能因其他原因而消失.因此,如果此视图不再是最顶层的视图,我只会取消隐藏栏 (2认同)

AI *_*ion 9

感谢@chad-m 的回答。

这是 Swift 版本:

  1. 创建一个新文件 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)
        }
    }

}
Run Code Online (Sandbox Code Playgroud)
  1. 将 StoryBoard 中的 UINavigationController 类设置为 MyNavigationController 我的导航控制器 就是这样!

chad-m 的答案和我的答案之间的区别:

  1. 继承自UINavigationController,所以不会污染你的rootViewController。

  2. 使用self.viewControllers.first而不是homeViewController,因此您不会为 1 个 StoryBoard 中的 100 个 UINavigationController 执行 100 次此操作。


小智 6

经过多次试验,我是如何让它按照我想要的方式工作的.这就是我的尝试. - 我有一个图像的视图.我想让图像全屏显示. - 我也有一个带tabBar的导航控制器.所以我也需要隐藏它. - 此外,我的主要要求不仅仅是隐藏,而是在显示和隐藏时也有褪色效果.

这就是我的工作方式.

第1步 - 我有一个图像,用户点击该图像一次.我抓住那个手势并将其推入新的imageViewController,它在imageViewController,我希望有全屏图像.

- (void)handleSingleTap:(UIGestureRecognizer *)gestureRecognizer {  
NSLog(@"Single tap");
ImageViewController *imageViewController =
[[ImageViewController alloc] initWithNibName:@"ImageViewController" bundle:nil];

godImageViewController.imgName  = // pass the image.
godImageViewController.hidesBottomBarWhenPushed=YES;// This is important to note. 

[self.navigationController pushViewController:godImageViewController animated:YES];
// If I remove the line below, then I get this error. [CALayer retain]: message sent to deallocated instance . 
// [godImageViewController release];
} 
Run Code Online (Sandbox Code Playgroud)

第2步 - 以下所有这些步骤都在ImageViewController中

步骤2.1 - 在ViewDidLoad中,显示navBar

- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
NSLog(@"viewDidLoad");
[[self navigationController] setNavigationBarHidden:NO animated:YES];
}
Run Code Online (Sandbox Code Playgroud)

步骤2.2 - 在viewDidAppear,设置延迟定时器任务(我将其设置为1秒延迟).并且在延迟之后,添加褪色效果.我使用alpha来使用淡入淡出.

- (void)viewDidAppear:(BOOL)animated
{
NSLog(@"viewDidAppear");

myTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self     selector:@selector(fadeScreen) userInfo:nil repeats:NO];
}

- (void)fadeScreen
{
[UIView beginAnimations:nil context:nil]; // begins animation block
[UIView setAnimationDuration:1.95];        // sets animation duration
self.navigationController.navigationBar.alpha = 0.0;       // Fades the alpha channel of   this view to "0.0" over the animationDuration of "0.75" seconds
[UIView commitAnimations];   // commits the animation block.  This Block is done.
}
Run Code Online (Sandbox Code Playgroud)

步骤2.3 - 在viewWillAppear,将singleTap手势添加到图像并使navBar半透明.

- (void) viewWillAppear:(BOOL)animated
{

NSLog(@"viewWillAppear");


NSString *path = [[NSBundle mainBundle] pathForResource:self.imgName ofType:@"png"];

UIImage *theImage = [UIImage imageWithContentsOfFile:path];

self.imgView.image = theImage;

// add tap gestures 
UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTap:)];  
[self.imgView addGestureRecognizer:singleTap];  
[singleTap release];  

// to make the image go full screen
self.navigationController.navigationBar.translucent=YES;
}

- (void)handleTap:(UIGestureRecognizer *)gestureRecognizer 
{ 
 NSLog(@"Handle Single tap");
 [self finishedFading];
  // fade again. You can choose to skip this can add a bool, if you want to fade again when user taps again. 
 myTimer = [NSTimer scheduledTimerWithTimeInterval:5.0 target:self  selector:@selector(fadeScreen) userInfo:nil repeats:NO];
 }
Run Code Online (Sandbox Code Playgroud)

第3步 - 最后viewWillDisappear,确保将所有东西都放回原处

- (void)viewWillDisappear: (BOOL)animated 
{ 
self.hidesBottomBarWhenPushed = NO; 
self.navigationController.navigationBar.translucent=NO;

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

[super viewWillDisappear:animated];
}
Run Code Online (Sandbox Code Playgroud)