はじめに、
NavigationController, TabBar、よく使いますね。基本的に、それなりにコンテンツがあるアプリだとこの2つは組み込まれているんじゃないでしょうか。
画面によってはナビバーを非表示にしたり、タブバーを非表示にしたり状況に応じて変えなければいけない場合もあると思います。
非表示設定といえば、いつの世もisHidden
系ですが、なるほどぉとなった部分があるので備忘録。
こんな場合あるよね
複数の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
の違いが気になる。