iOS 15でNavigationBarとTabBarがデフォルトで透過される
iOS 15をXcode 13以上で開発していたところ、NavigationBarとTabBarの背景が透過されていることがわかりました。
どうやらXcode 13でビルドをした場合、iOS 15のNavigationBarとTabBarはデフォルトで背景が透過されるようです。
私のアプリでは透過ではなく、iOS 14以前と同じように背景色をつけたかったので、どう修正するのかを調べました。
開発環境
- Xcode 13.2
- iOS 15.2
NavigationBarをiOS 14以前と同じ見た目にする
背景色が透過されるようになった原因
UINavigationBar
にはscrollEdgeAppearance
というプロパティがあります。
UINavigationBarAppearance
というNavigationBarの外観設定を司るクラスのインスタンスです。
Navigation ControllerがNavigation BarとScroll Viewを持っている場合で、Scroll Viewのコンテンツの端がNavigation Barに到達したときに外観設定が適応されます。
公式ドキュメントを読むと、scrollEdgeAppearance
はnilの場合に、standardAppearance
を利用するのですが、そのデータが背景を透明にするものになっているとのことです。
この適応はiOS 14以前では「大きなタイトル(ラージタイトル)」を持つNavigation Barのみでしたが、iOS 15ではすべてのNavigation Barに適応されたとのことです。
動作を確認したgifがこちらです。
確かにスクロールでコンテンツが端に到達した場合は透明に、そうでない場合は背景色がつくようになっています。
ちなみに「大きなタイトル」を適応するにはprefersLargeTitles
をtrueにセットすればよいです。
navigationController?.navigationBar.prefersLargeTitles = true
UINavigationBarの外観設定の種類
UINavigationBar
にはscrollEdgeAppearance
の他にstandardAppearance
とcompactAppearance
という外観設定のインスタンスが用意されています。
それぞれの使いみちは次の通りです。
- standardAppearance: 通常のNavigationBarの外観設定
- compactAppearance: iPhoneで横向きの場合のNavigationBarの外観設定
- scrollEdgeAppearance: Scroll Viewのコンテンツの端がNavigation Barに到達したときの外観設定
詳細は以前ブログで解説しています。お時間のある方はこちらもご参照ください。
修正コード
次のようにコードをAppDelegate
のapplication(_:didFinishLaunchingWithOptions:)
メソッドなどの必ずアプリが実行する場所に実装しましょう。
そうするとiOS 14と同じ外観になります。
if #available(iOS 15.0, *) {
// disable UINavigation bar transparent
let navigationBarAppearance = UINavigationBarAppearance()
navigationBarAppearance.configureWithDefaultBackground()
UINavigationBar.appearance().standardAppearance = navigationBarAppearance
UINavigationBar.appearance().compactAppearance = navigationBarAppearance
UINavigationBar.appearance().scrollEdgeAppearance = navigationBarAppearance
}
navigationBarAppearance
をconfigureWithDefaultBackground
でデフォルトの背景色を設定し、standardAppearance
、compactAppearance
、scrollEdgeAppearance
に代入しています。
背景色を透明にしているのはscrollEdgeAppearance
ですが、同じ設定をstandardAppearance
、compactAppearance
にも適応して設定をそろえています。
こうすることでiOS 15でもiOS 14と同じ見た目にできます。
TabBarをiOS 14以前と同じ見た目にする
背景色が透過されるようになった原因
TabBarもscrollEdgeAppearance
がiOS 15から導入されました。
Navigation Barの
scrollEdgeAppearance
はiOS 13から導入
用途はNavigation Barと同じです。
Tab Bar ControllerがTab BarとScroll Viewを持っている場合、Scroll Viewのコンテンツの端がTab Barに到達した場合の外観設定を行います。
nilの場合はstandardAppearance
を利用するのですが、そのデータが背景を透明にするものになっているため、iOS 15のみが背景透過されてしまいます。
scrollEdgeAppearance | Apple Developer Documentation
修正コード
Navigation Barと同じくAppDelegate
のapplication(_:didFinishLaunchingWithOptions:)
メソッドなどの必ずアプリが実行する場所でscrollEdgeAppearance
にデフォルトの背景色を設定します。
そうするとiOS 14と同じ外観になります。
if #available(iOS 15.0, *) {
// disable UITab bar transparent
let tabBarAppearance: UITabBarAppearance = UITabBarAppearance()
tabBarAppearance.configureWithDefaultBackground()
UITabBar.appearance().scrollEdgeAppearance = tabBarAppearance
UITabBar.appearance().standardAppearance = tabBarAppearance
}
このコードではstandardAppearance
も同じ設定でそろえています。
standardAppearance
は通常の場合の外観設定に使われるものです。
まとめ
iOS 15によるNavigation BarとTab Barの外観のデフォルト値が背景透明になる現象と、iOS 14以前の見た目に戻すコードを紹介しました。
OSが変わるとデフォルトの動きも変わることがあるのは仕方がないことですね。
一つずつ見つけて直していきましょう。
参考URL
- How to disable automatic transparent tabBar in iOS 15 | Filip Němeček
- How to disable automatic transparent navbar in iOS 15 | Filip Němeček
- iOS 13でのNavigationBarのカスタマイズ方法
宣伝
インプレスR&D社より「一冊でマスター!Swift Concurrency入門」が発売中です。
Swift Concurrencyを網羅的に学べ、さらに既存アプリへの適応方法も解説しています。
日本語で体系的に学べる解説本は他にありません。
ぜひチェックしてみてください!