LoginSignup
5
4

More than 3 years have passed since last update.

画面遷移時のNavigationBar/TabBarの表示・非表示操作

Posted at

はじめに、

NavigationController, TabBar、よく使いますね。基本的に、それなりにコンテンツがあるアプリだとこの2つは組み込まれているんじゃないでしょうか。

画面によってはナビバーを非表示にしたり、タブバーを非表示にしたり状況に応じて変えなければいけない場合もあると思います。
非表示設定といえば、いつの世もisHidden系ですが、なるほどぉとなった部分があるので備忘録。

こんな場合あるよね

IMG_782B86A5410B-1.jpeg

複数のVCから特定のVCに遷移するケース。
2階層以降なのでタブバー が非表示になるのはわかりますが、デザインのあれこれでナビバーがない画面を実装する時、隠す実装をする。そして、元の画面に戻った時用に再表示する。

表示/非表示系メモ

このケースを実装する時の発想として以下のものがある。

Q : SharedVCが表示されたら隠して、閉じたら表示する
A : まとめて設定すると、いろんな画面に対応できない

Q : 遷移元のVCをクラス判定して表示の分岐をしてみては
A : かなり限定的ならいいが、所々でシェアされてるのでより抽象化共通処理を狙いたい

という部分で、以下の結論に至った。

コード

// 遷移元VCがナビバー・タブバーを持っているかの状態を保持するインスタンス
private var hasPreviousVCNaviBar = true
private var hasPreviousVCTabBar = true

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)

    // 遷移元の状態を設定
    hasPreviousVCNaviBar = navigationController?.isNavigationBarHidden == true ? false : true
    hasPreviousVCTabBar = tabBarController?.tabBar.isHidden == true ? false : true
    // SharedVC自体の表示処理をする
    navigationController?.isNavigationBarHidden == true
    tabBarController?.tabBar.isHidden = true
}

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)

    // VCが消滅するときに、保存した遷移元の状態に合わせて設定し直す
    navigationController?.isNavigationBarHidden = !hasPreviousVCNaviBar
    tabBarController?.tabBar.isHidden = !hasPreviousVCTabBar
}

注意点

遷移元VCにアクセス?

注意したいのは、 遷移元のVCにここでアクセスしてナビタブの状態を確認しようとする行為がよろしくないということ。
画面ごとにナビタブの非表示設定をしているわけではなく、ナビタブの配下にviewControllersがあるので

let prevVC = presentingViewController
prevVC.navigationController

としても、上で設定変えちゃってますよということ。階層をイメージしていればわかる話何ですが。

hidesBottomBarWhenPushedでタブバー隠し

hidesBottomBarWhenPushedもタブバーの非表示処理ですが、これらライフサイクルメソッドに突入してからの実装だとそのVCに反映されません。
なので、これを実装する場合は

sharedVC.hidesBottomBarWhenPushed = true
show(sharedVC, sender: nil)

という風に遷移前に設定する必要があります。
これでもいいですが、遷移メソッド実装するごとに設定をするのが面倒です。
遷移メソッド自体をカスタムしたりもできると思いますが、大元で設定する方が楽です。

NavigationBar の hide処理多すぎ問題

navigationController?.navigationBar.isHidden = true
navigationController?.isNavigationBarHidden == true
navigationController?.setNavigationBarHidden(true, animated: true)

なんか3つほどあります。
.setNavigationBarHiddenに関してはアニメーションを付与したいかどうかの違いです。
.navigationBar.isHidden.isNavigationBarHiddenの厳密な違いはわからないのですが、.isHiddenは上記の条件だと機能しませんでした。(エラーはなく補完もあるのに)

ナビバーを非表示処理する際は.setNavigationBarHidden良さそうですね。

まとめ

該当するもの(型とか)で分岐という方法もあるが、コンテンツの肥大化等を考慮したときに、出来るだけ抽象化しておくのは大きいメリットだなと感じました。
あと.isHiddenの違いが気になる。

5
4
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
4