399

ナビゲーションバーを非表示および表示する以下のコードがあります。最初のビューが読み込まれると非表示になり、「子」が呼び出されると非表示になります。問題は、ルートビューに戻ったときに、イベント/アクションをトリガーして再び非表示にするイベント/アクションが見つからないことです。

ルートページに手動でアクションを実行する「テスト」ボタンがありますが、きれいではないので自動にしたいです。

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

14 に答える 14

1056

私が見つけた最も良い解決策は、最初の View Controllerで次のことを行うことです。

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

迅速

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これらのメソッドの の実装をオーバーライドしています。ドキュメントによると、実装のどこかでスーパーの実装を呼び出す必要があります

于 2010-03-09T01:59:42.917 に答える
74

私が見つけた別のアプローチは、のデリゲートを設定することです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それぞれの動作を1 か所で簡単にカスタマイズできます。

于 2011-06-20T23:11:44.073 に答える
19

他の答えに対して私がしなければならなかったわずかな微調整の1つは、バーが消える理由がナビゲーションアイテムが押されたためである場合にのみ、viewWillDisappearでバーを再表示することです。これは、他の理由でビューが消える可能性があるためです。

したがって、このビューが最上位のビューでなくなった場合にのみ、バーを再表示します。

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

    [super viewWillDisappear:animated];
}
于 2010-11-20T19:09:11.580 に答える
18

表示されている各ビューのviewWillAppearデリゲートにコードを配置します。

あなたがそれを隠す必要があるこのように:

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

あなたがそれを示す必要があるこのように:

- (void)viewWillAppear:(BOOL)animated
{
        [yourObject showBar];
}
于 2009-05-10T16:23:58.533 に答える
15

現在受け入れられている回答は、質問に記載されている意図した動作と一致しません。この質問では、ナビゲーション バーをルート ビュー コントローラーでは非表示にするが、それ以外の場所では表示するよう求めていますが、受け入れられた回答では、特定のビュー コントローラーでナビゲーション バーが非表示になります。最初のView Controllerの別のインスタンスがスタックにプッシュされるとどうなりますか? ルート ビュー コントローラーを見ていない場合でも、ナビゲーション バーが非表示になります。

代わりに、を使用する@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];
    }
}
于 2014-10-09T02:05:46.787 に答える
14

スウィフト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)
}
于 2015-02-05T15:15:12.157 に答える
6

複数の試行錯誤の後、私が望むもののためにそれをどのように機能させたかを以下に示します。これが私が試していたものです。- 画像付きのビューがあります。画像を全画面表示にしたかったのです。- tabBar を備えたナビゲーション コントローラーもあります。だから私もそれを隠す必要があります。- また、私の主な要件は、単に隠すだけではなく、見せたり隠したりしながらフェード効果を持たせることでした。

これが私がそれを機能させた方法です。

ステップ 1 - 画像があり、ユーザーがその画像を 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];
} 

ステップ 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];
}

ステップ 2.2 -viewDidAppearで、遅延のあるタイマー タスクを設定します (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で、シングルタップ ジェスチャを画像に追加し、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];
 }

ステップ 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];
}
于 2011-12-11T17:14:42.877 に答える
4

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

私の場合、ルート ビュー コントローラー (ナビゲーションが非表示になっている) とプッシュされたビュー コントローラー (ナビゲーションが表示されている)のステータス バーのスタイルが異なる(たとえば、ダークとライト) ためであることがわかりました。バックスワイプを開始してビュー コントローラーをポップすると、ステータス バーのカラー アニメーションが追加されます。インタラクティブ ポップをキャンセルするために指を離すと、ステータス バーのアニメーションが終了しないうちに、ナビゲーション バーが消えてしまいます。

ただし、両方のビュー コントローラーのステータス バーのスタイルが同じ場合、このバグは発生しません。

于 2016-08-02T07:01:40.823 に答える
0

最も単純な実装は、各ビュー コントローラーにナビゲーション バーを非表示にするかどうかをviewWillAppear:animated:メソッドで指定させることです。ツールバーの非表示/表示にも同じアプローチがうまく機能します。

- (void)viewWillAppear:(BOOL)animated {
    [self.navigationController setToolbarHidden:YES/NO animated:animated];
    [super viewWillAppear:animated];
}
于 2011-11-30T23:18:02.677 に答える
-1

このコードをViewControllerに実装することで、この効果を得ることができます

- (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];
}
于 2016-08-02T11:31:59.900 に答える