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

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

-(void)hideBar 
{
    self.navController.navigationBarHidden = YES;
}
-(void)showBar 
{       
    self.navController.navigationBarHidden = NO;
}
有帮助吗?

解决方案

我发现的最好的解决方法是在做的第一视图控制器以下

<强>目标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];
}

<强>夫特

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)
} 

这将导致导航栏在从左侧(与下一个视图一起)动画时你推栈上的下一个UIViewController,以及(与旧视图一起)动画至左侧,当按下在UINavigationBar后退按钮。

请还请注意,这些都不是委托方法,你将覆盖UIViewController的实现这两个方法,并根据您文件的某处必定调用父类的实现在执行

其他提示

我发现的另一种方法是设置为NavigationController委托:

navigationController.delegate = self;

和使用setNavigationBarHidden navigationController: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];
}

简单的方法来定制在一个地方每个ViewController行为。

一个轻微的调整,我不得不做出对其他的答案是,如果它正在消失的原因是由于导航项目上推到仅取消隐藏在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];
}

在夫特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)
}

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

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

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

该解决方案的完整代码可以在以下位置找到 这个要点. 。这是 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];
    }
}

多次试验后,这里是我得到了它就是我想要的工作。 这是我尝试。 - 我有一个图像的图。我想有像进入全屏模式。 - 我有一个导航控制器具有的TabBar了。所以我需要掩饰这一点。 - 此外,我的主要要求是不仅隐藏,但是具有衰落效应的同时也显示和隐藏

这是我如何得到它的工作。

步骤1 - I有一个图像和用户轻敲该图像上一次。我捕捉手势,并将它推到新的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];
} 

步骤2 - 下面所有这些步骤都在ImageViewController

步骤2.1 - 在viewDidLoad中,显示导航栏

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

步骤2.2 - 在viewDidAppear,设置了延迟(I有它设置为1秒延迟)的定时器任务。和延迟后,添加淡入效果。我使用阿尔法使用褪色。

- (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.
}

步骤2.3 - 在viewWillAppear,singleTap手势添加到图像,使导航栏半透明的。

- (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];
 }

第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];
}

请相信@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)
        }
    }

}
  1. 将 StoryBoard 中的 UINavigationController 类设置为 MyNavigationControllerMyNavigationController 就是这样!

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

  1. 继承自UINavigationController,这样就不会污染你的rootViewController。

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

在任何人的情况下仍具有与在快速backswipe取消错误如@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被示出)的有不同的状态栏样式(例如深色和浅色)。启动backswipe弹出视图控制器的那一刻,会有额外的状态栏的颜色动画。如果您松开手指,以消除交互流行,,而状态栏动画还没有完成后,导航栏已经一去不复返了!

然而,如果状态栏样式两个视图控制器的是相同的,不会发生这种错误。

如果你想要的是完全隐藏导航栏控制器,一个更清洁的解决办法是,在根控制器,碰到这样的:

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

当你在控制器推子视图,导航栏将保持隐藏;如果你只想在孩子来显示它,您将要添加的代码在it(self.navigationController.navigationBarHidden=NO;)回调显示viewWillAppear,同样的代码隐藏它viewWillDisappear

在最简单的实现可能是只是有每个视图控制器指定其导航栏是否在其viewWillAppear:animated:方法隐藏或没有。同样的方法可以很好地用于隐藏/显示工具栏,以及:

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

仅在第一页隐藏导航栏可以通过故事板来实现,以及。上故事板,转到导航控制器Scene->导航。和从属性检查员选择 '隐藏' 属性。这将隐藏的导航栏从第一视图 - 控制开始,直到它所需的视图 - 控制可见。

导航栏可以被设置回可见的ViewController的viewWillAppear中回调。

-(void)viewWillAppear:(BOOL)animated {

    [self.navigationController setNavigationBarHidden:YES animated:animated];
    [super viewWillAppear:animated];                                                  
}

<强>夫特4:

在视图控制器要隐藏从导航栏。

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)
}

通过在您的视图控制器实现此代码,你可以得到这样的效果  实际上诀窍是,隐藏的导航栏时控制器启动

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

和取消隐藏导航栏时用户离开该网页做到这一点是viewWillDisappear

- (void)viewWillDisappear:(BOOL)animated {
    [self.navigationController setNavigationBarHidden:NO animated:YES];
    [super viewWillDisappear:animated];
}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top