[SwiftUI] NavigationView の background を指定する

SwiftUI

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

NavigationView の background は、期待と違う

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

NavigationView code

//
//  ContentView.swift
//
//  Created by : Tomoaki Yagishita on 2020/11/23
//  © 2020  SmallDeskSoftware
//

import SwiftUI

struct ContentView: View {
    var body: some View {
        NavigationView {
            NavigationLink("another view", destination: Text("Another view"))
                // (1)
                .background(Color.green)
        }
        // (2)
        .background(Color.red)
    }
}
コード解説
  1. NavigationLink にも background 指定してみました(gree)
  2. NavigationView にも background 指定しています(red)

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

NavigationView background 指定

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

UIKit を使う

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

example code

UIView.appearance().backgroundColor = UIColor.red

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

NavigationView UIView 指定

「NavigationView UIView 指定」

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

ZStack を使う

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

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

NavigationView with ZStack

//
//  ContentView.swift
//
//  Created by : Tomoaki Yagishita on 2020/11/23
//  © 2020  SmallDeskSoftware
//

import SwiftUI

struct ContentView: View {
    var body: some View {
        NavigationView {
            ZStack {
                // (1) ZStack を使って Color.red を重ねて表示
                Color.red
                NavigationLink("another view", destination: Text("Another view"))
                    .background(Color.green)
            }
        }
    }
}

NavigationView with ZStack

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

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

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

UIKit と ZStack を組み合わせる

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

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

NavigationView with ZStack/UINavigationBar

//
//  ContentView.swift
//
//  Created by : Tomoaki Yagishita on 2020/11/23
//  © 2020  SmallDeskSoftware
//

import SwiftUI

struct ContentView: View {
    var body: some View {
        NavigationView {
            ZStack {
                Color.red
                NavigationLink("another view", destination: Text("Another view"))
                    .background(Color.green)
            }
        }
        .onAppear{
            UINavigationBar.appearance().backgroundColor = UIColor.red
        }
    }
}

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

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

コメントを残す

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