[SwiftUI] NavigationView での タイトル指定で注意すべきこと

SwiftUI

     

TAGS:

⌛️ 2 min.
SwiftUI の NavigationView は、便利ですよね。
でも、画面上部に微妙なスキマ(?)ができてしまうことありませんか?
その理由と解決方法を説明します。

NavigationView の使い方

いわゆる階層的に、上下する時に使われるかと思います。

アイテムのリストがあって、そのアイテムをクリックするとアイテムの詳細を表示するビューに遷移したり。

とくに、iOS だとほとんどのアプリケーションで使われている操作体系なので、使う側も使い慣れてます。

SwiftUI では、NavigationView と NavigationLink を使って、作っていくのが1つのやり方です。

以下のコードは、最初の画面に “To Child” というボタンがあって、そのボタンが押されると、子ビューに遷移するコードです。

# 画面の要素の範囲をわかりやすくするために、ボーダーを表示してます。

コード


struct ContentView: View {
    var body: some View {
        NavigationView {
            NavigationLink(destination: ChildView(), label: {
                    Text("to Child")
            })
                .frame(maxWidth:.infinity, maxHeight: .infinity)
                .border(Color.orange, width: 5)
                .navigationBarTitle("NavBar")
        }
        .navigationViewStyle(StackNavigationViewStyle())
    }
}
struct ChildView: View {
    var body: some View {
        Text("Child")
            .frame(maxWidth:.infinity, maxHeight: .infinity)
            .border(Color.orange, width: 5)
    }
}

起動時画面
InitialViewRev1

遷移後の画面
SecondViewRev1

気になる点

先の画面を見て、気づくと思いますが、遷移後の画面のタイトル周りの空間が気になりますよね。
SecondViewRev0Mentioned

特に何も配置しているつもりがなくても、スペースが空いてしまって、バランスも悪くも見えます。

NavigationView のタイトルのスペース

実は、.navigationBarTitle がこの配置に影響を与えています。

.navigationBarTitle を使うことで、NavigationView にタイトルを表示することができます。

例えば、起動時画面では、.navigationBarTitle(“NavBar”) とすることで、”NavBar” というタイトルが表示されているのがわかります。

2画面目には、タイトルを指定していないのですが、指定しなくてもタイトルがなくなるわけではありません。

ここが落とし穴の1つ目で、指定していなくとも、何らかのタイトルを表示しようとして、先のスペースが作られています。




じゃぁ、タイトルを空文字にしたら?

では、指定すれば良いでしょ? ということになるかと思います。例えば、以下のように指定してみます。

コード


struct ChildView: View {
    var body: some View {
        Text("Child")
            .frame(maxWidth:.infinity, maxHeight: .infinity)
            .border(Color.orange, width: 5)
            .navigationBarTitle("ChildView")
    }
}

SecondViewRev0Title

意味不明なスペースは無くなりましたが、タイトルそこまで大きくしなくても・・・・ というのが大抵の人の受ける印象かと思います。

タイトル指定時のオプション displayMode

大抵のアプリケーションでは、NavigationView の2階層目以降は、タイトルが小さめに表示されると思います。その点で、さきほどのビューには、違和感を感じるわけです。

SwiftUI でも NavigationView で階層化されたビューでのタイトルの大きさについての制御ができるようになっています。

具体的には、 .navigationBarTitle での指定には、2つめの引数を指定することができます。この引数によってタイトル表示の大きさを制御することができます。

2つ目の引数は、 displayMode で、値としては、automatic, inline, large を指定することができます。

automatic
直前の Navigation Item の設定を引き継いで使用します
inline
通常の Navigation Bar に収まるようにタイトルを表示します
large
Navigation Bar の枠を広げて、タイトルを大きく表示します

覚えておいた方が良い点として、デフォルトでは、automatic が適用されると言う点です。

先の例ですと、ChildView で NavigationView のタイトルは指定していますが、displayMode は指定していないので、親ビューの設定を引き継いで large 指定されたことになっています。

このことが、タイトル周りに不自然なスペースが配置される理由です。

不自然なスペースの解決策

タイトルを、large ではなく、inline 指定で表示することで、タイトルを Navigation Bar に収めるように表示させることが可能です。

コード


struct ChildView: View {
    var body: some View {
        Text("Child")
            .frame(maxWidth:.infinity, maxHeight: .infinity)
            .border(Color.orange, width: 5)
            .navigationBarTitle("ChildView", displayMode: .inline)
    }
}

SecondViewRev1In

タイトルに、空文字を指定することで、スッキリさせることもできます。

コード


struct ChildView: View {
    var body: some View {
        Text("Child")
            .frame(maxWidth:.infinity, maxHeight: .infinity)
            .border(Color.orange, width: 5)
            .navigationBarTitle("", displayMode: .inline)
    }
}

SecondViewRev1WithoutTitle

# なお、NavigationView には、タイトルバーを非表示にするオプションはありますが、タイトルをなくすオプションはありません。




まとめ:NavigationView のタイトル指定で気をつけること

以下の2点です。

  • NavigationView には、常にタイトルが表示される(ので、意識しておく必要がある)
  • NavigationView のタイトル設定のデフォルトは、automatic で直前の表示設定を引き継ぐ(ので、意識しておく必要がある)

2画面目以降は、inline 指定しないと、今回のように、タイトルバーが”意図せず”大きくなってしまうことになります。

説明は以上です。

1 COMMENT

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です