[SwiftUI] NavigationView の background を指定する

SwiftUI

SwiftUI の background を指定する方法を説明します。

NavigationView の background は、期待と違う

NavigationView の背景を指定しようとして以下のようなコードを書いてみると期待と違うことに気づきます。

NavigationView code

コード解説
  1. NavigationLink にも background 指定してみました(gree)
  2. NavigationView にも background 指定しています(red)

次のようになってしまいます。

NavigationView background 指定

「NavigationView background 指定」
NavigationLink には、background 指定が反映されていますが、NavigationView には、反映されているように見えません。

UIKit を使う

StackOverflow 等を探してみると、UIKit を使った例が見つかります。

example code

NavigationView.onAppear に設定してみると以下のようになります。

NavigationView UIView 指定

「NavigationView UIView 指定」

NavigationView の NavigationBar の部分は、塗られましたが、内側は塗られていません。NavigationLink の方は、SwiftUI の background 指定が UIKit での指定で上書きされてしまっているようです。

ZStack を使う

もう少しシンプルなソリューションを試してみました。

NavigationView の内側の背景を指定したいので、NavigationView の内側に ZStack 指定して背景を重ねてみました。

NavigationView with ZStack

NavigationView with ZStack

「NavigationView with ZStack」
NavigationView の内側と NavigationLink の設定はうまくいきました。

ただ、タイトルバーの背景が処理されてません。

NavitagionView の内部に ZStack を入れていますので、タイトルが処理されないのは、設計通りだと思います。

UIKit と ZStack を組み合わせる

NavigationView の タイトルバー を指定する方法は、SwiftUI 的には無いようです。

UINavigationBar.appearance().backgroundColor で、UIKit 経由で指定するしか無いようです。

NavigationView with ZStack/UINavigationBar

NavigationView with ZStack/UINavigationBar

「NavigationView with ZStack/UINavigationBar」

ZStack と UINavigationBar.appearance を同時に使うことで、NavigationView 配下要素の背景を指定することができました。

# よくみると、(SwiftUIの) Color.red と (UIKitの) UIColor.red が違うことがわかります。
# Color.red を Color(UIColor.red) とすることで、UIColor と同じ赤になります。

タイトル使わない

別の方法として、タイトル使わないという方法もあります。

.navigationBarHiddlen(true) と指定することで、タイトルが表示されなくなりますので、UIKit を使わずに解決することもできます。

まとめ:NavigationView の background を指定する方法

NavigationView の background を指定する方法
  • タイトルは、UINavigationBar.appearance() 経由で指定する
  • 内部は、ZStack を使い、既存要素と重ねて表示させることで指定する

SwiftUI本

SwiftUI で開発していくときに、ViewやLayoutのための適切なmodifierを探すのが大変です。
以下の”SwiftUI Views Mastery Bundle”という本がビジュアル的に確認して探せるので、超便利です。

SwiftUIViewsMastery

説明は以上です。
不明な点やおかしな点ありましたら、ご連絡いただけるとありがたいです。

コメントを残す

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