はじめに
皆さんは Large Title 使っていますか?
iOS 11 から 全体的に太字のデザインに変わって少し残念に
思っていたのですが,Large Title だけは好きでよく使っています。
iOS 13 から表示が変わって対応に少し困ったので調べてみました。
UINavigationBarAppearance
1 というのが追加されています。
iOS 13 の NavigationBar の見た目が変わった
多くのアプリではテーマカラーを持っており,NavigationBar
の
色設定にテーマカラーやそれ相当の色を充てていたりします。
私のアプリもテーマカラーを充てています。
iOS 13 対応を行う際に Xcode 11 でビルドしたアプリを見ていて
Large Title を使っている部分の表示に違和感を感じました。
NavigationBar
の barTintColor
を設定していないと
あまり気にならないですが,
Large Title 表示時の NavigationBar
の色がなくなり背景と同化しています。
通常時は,問題なく想定通りです。
下記が実際のアプリでの表示です。
Large Title 表示時(背景に溶け込んでいる)
iOS 11, 12 | iOS 13 ⁉️ |
---|---|
![]() |
![]() |
通常時(問題ない)
iOS 11, 12 🆗 | iOS 13 🆗 |
---|---|
![]() |
![]() |
iOS 13 から NavigationBar
をデフォルトで透過させるようにしたようです。
そのため,self.view
の Background Color
と同化して見えるということです。
(上の例は UITableViewController
のため,UITableView
の色 Grouped Table View Color
になっている)
モーダルのデフォルト表示スタイルの変更(Sheet)もそうだけど
デフォルトを変更する(変更を強いる)のやめて欲しい・・・
UINavigationBarAppearance
とは
iOS 13 からは UINavigationBarAppearance
を用いて,
NavigationBar
周りのデザインをカスタマイズするようです。
UINavigationBarAppearance
は UIBarAppearance
2 のサブクラスで,
親戚に UIToolBarAppearance
や UITabBarAppearance
などもあります。
設定できる外観(Appearance)は3種類です。
.standardAppearance
.compactAppearance
.scrollEdgeAppearance
.standardAppearance
はいわゆる通常の 44pt のもの。
.compactAppearance
は Landscape の低い高さのもの。

.scrollEdgeAppearance
はラージタイトル用のもの。
スクロールビューがトップに来たときの表示。

NavigationBar
のタイトルやフォント Large Title のカスタマイズは
iOS 12 までと同様に設定できるようです。
titleTextAttributes
largeTitleTextAttributes
iOS 12 までは下記のように書いていました。
self.navigationController?.navigationBar.largeTitleTextAttributes =
[NSAttributedString.Key.foregroundColor: UIColor.white,
NSAttributedString.Key.font: UIFont.boldSystemFont(ofSize: 30.0)]
iOS 13 からは書き方が変わります。
// インスタンス生成
let appearance = UINavigationBarAppearance()
// 設定をリセット
appearance.configureWithDefaultBackground()
// ここに適用させたい設定を書く
// Large Title 表示用設定
self.navigationController?.navigationBar.scrollEdgeAppearance = appearance
// 通常表示時の設定
self.navigationController?.navigationBar.standardAppearance = appearance
設定のリセットは3種類あります。
使い分けはいまいちわからないです・・・
@available(iOS 13.0, *)
open class UIBarAppearance : NSObject, NSCopying, NSSecureCoding {
/// Reset background and shadow properties to their defaults.
open func configureWithDefaultBackground()
/// Reset background and shadow properties to display theme-appropriate opaque colors.
open func configureWithOpaqueBackground()
/// Reset background and shadow properties to be transparent.
open func configureWithTransparentBackground()
iOS 13 でも iOS 11 や 12 でも同じ Large Title の表示にしたい
サンプルプロジェクトを用意しました。
適宜参考にしてください。
GitHub: https://github.com/MilanistaDev/NewLargeTitleSample
環境
- Xcode 11
- サポート:iOS 11以上(場合分けが増えるため)
- iOS 12 端末
- iOS 13 端末
要件
- TableView をスクロールすると Large Title が隠れて NavigationBar のタイトルとなる
- NavigationBar の色は赤で,タイトル色は黒
- iOS 13 ではライトモードでタイトルの色は黒,ダークモードでは白とする
(指定は赤だけどライトモードとダークモードとで色味が変わる .systemRed
の方が良い)
以下,現行コードから移行する感じで書いていきます。
まず,iOS 11, 12 で想定している表示となるコードは下記です。
(長くなるので TableView 周りの実装は省きます。)
class ViewController: UIViewController {
@IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
self.setUpNavigationBar()
}
private func setUpNavigationBar() {
// Large Title Basic Settings
self.navigationItem.title = "Large Title"
self.navigationController?.navigationBar.prefersLargeTitles = true
self.navigationItem.largeTitleDisplayMode = .always
self.navigationController?.navigationBar.barTintColor = .red
}
}
これで iOS 12 端末で実行すると問題なく表示されます。
iOS 13 では,通常表示の場合は正しく赤色が設定されていますが,
Large Title 表示時は透過しており,赤色が出ていません。
iOS 12 🆗 | iOS 13 🤔 |
---|---|
![]() |
![]() |
UINavigationBarAppearance
を用いて iOS 13 の NavigationBar 設定を行います。
iOS 11, 12 の場合と場合分けする必要があります。
private func setUpNavigationBar() {
// Large Title Basic Settings
// abbreviation 略
if #available(iOS 13.0, *) {
let appearance = UINavigationBarAppearance()
appearance.configureWithDefaultBackground()
appearance.backgroundColor = .red // .systemRed の方が望ましい
appearance.largeTitleTextAttributes = [.foregroundColor: UIColor.label]
appearance.titleTextAttributes = [.foregroundColor: UIColor.label]
// Large Title 用 NavigationBar の色設定
self.navigationController?.navigationBar.scrollEdgeAppearance = appearance
// 通常の NavigationBar の色設定
self.navigationController?.navigationBar.standardAppearance = appearance
} else {
// iOS 13 未満はこれまで通り
self.navigationController?.navigationBar.barTintColor = .red
}
}
これでちゃんと表示されるようになりました!
largeTitleTextAttributes
と titleTextAttributes
もあるので
テキストカラーとサイズを変更する場合も容易ですね。
Large Title のポジションもある程度カスタマイズできるようです。
titlePositionAdjustment
を下記のように調整します。
appearance.titlePositionAdjustment = UIOffset(horizontal: CGFloat , vertical: CGFloat)
こんなふうに左側に寄せることもできますね。
vertical
の方は使い勝手難しそう。
おわりに
今回は,iOS 13 の Large Title 表示を iOS 12 までと同じデザインにする実装に関して書きました。UINavigationBarAppearance
ってどこで説明されてたの?って思いましたが,ちょうど見忘れていたセッションで説明が軽くありました。
リリースしたアプリはこの対応していないので早速実装しようと思います。
ご覧いただきありがとうございました!!
参考
今回参考にしたセッションは細かいけど大事なことが詰め込まれているセッションです。
Modernizing Your UI for iOS 13
https://developer.apple.com/videos/play/wwdc2019/224/
【iOS11】NavigationBarのlargeTitlesの文字をカスタマイズする
https://qiita.com/MilanistaDev/items/4ff029c2e93bd5357fbd