でも、画面上部に微妙なスキマ(?)ができてしまうことありませんか?
その理由と解決方法を説明します。
Sponsor Link
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)
}
}
起動時画面
遷移後の画面
気になる点
先の画面を見て、気づくと思いますが、遷移後の画面のタイトル周りの空間が気になりますよね。
特に何も配置しているつもりがなくても、スペースが空いてしまって、バランスも悪くも見えます。
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")
}
}
意味不明なスペースは無くなりましたが、タイトルそこまで大きくしなくても・・・・ というのが大抵の人の受ける印象かと思います。
タイトル指定時のオプション 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)
}
}
タイトルに、空文字を指定することで、スッキリさせることもできます。
struct ChildView: View {
var body: some View {
Text("Child")
.frame(maxWidth:.infinity, maxHeight: .infinity)
.border(Color.orange, width: 5)
.navigationBarTitle("", displayMode: .inline)
}
}
# なお、NavigationView には、タイトルバーを非表示にするオプションはありますが、タイトルをなくすオプションはありません。
まとめ:NavigationView のタイトル指定で気をつけること
以下の2点です。
- NavigationView には、常にタイトルが表示される(ので、意識しておく必要がある)
- NavigationView のタイトル設定のデフォルトは、automatic で直前の表示設定を引き継ぐ(ので、意識しておく必要がある)
2画面目以降は、inline 指定しないと、今回のように、タイトルバーが”意図せず”大きくなってしまうことになります。
説明は以上です。
Sponsor Link
[…] ・ツールバー NavigationViewって名前になったのでこれを使う タイトルがデフォルトだと無茶苦茶でかいやつになるので以下を指定する navigationBarTitle(“aaaa”, displayMode: .inline) https://software.small-desk.com/development/2020/08/26/swiftui-navigationview-tips/ […]