この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
SwiftUIでList
を使用すると背景色はデフォルトで薄いグレーのようなカラーになっています。デフォルトの色以外に変更したかったので調べることにしました。
環境
- Xcode 13.3
デフォルトの色
List
を表示してみました。
import SwiftUI
struct ContentView: View {
var body: some View {
List {
Text("あれ?")
Text("声が")
Text("遅れて")
Text("聞こえてるよ")
}
}
}
デフォルトでは、このようなグレーの色になっております。
色を変更させようとして.tint
や.background
を使用しても変更出来ませんでした。
UITableView.appearance().backgroundColorを使用する
List
の背景色を変更させるためにUITableView.appearance().backgroundColor
を使用します。
import SwiftUI
struct ContentView: View {
init() {
UITableView.appearance().backgroundColor = .orange
}
var body: some View {
List {
Text("あれ?")
Text("声が")
Text("遅れて")
Text("聞こえてるよ")
}
}
}
init
メソッド時にUITableView.appearance().backgroundColor
に変更したい色を代入しています。
これでList
の背景色が変更出来ました。
Listのextensionを作成する
上記で記載した方法をextensionメソッドを作成して実施してみます。
UITableView.appearance().backgroundColor
に変更したい色を代入して、Viewを返すメソッドをList
の extensionとして作成します。今回はList
のexntensionですがForm
なども該当する為、View
のextensionでも良いかもしれません。
import SwiftUI
extension List {
func listBackground(_ color: Color) -> some View {
UITableView.appearance().backgroundColor = UIColor(color)
return self
}
}
Listのextensionを使用する
作成したextensionメソッドを使用する際は下記のように使用します。
import SwiftUI
struct ContentView: View {
var body: some View {
List {
Text("あれ?")
Text("声が")
Text("遅れて")
Text("聞こえてるよ")
}
.listBackground(.blue)
}
}
同じようにList
の背景色が変更出来ました。
NavigationViewと一緒に使用してみると
NavigationView
と.listBackground(_ color:)
を一緒に使用してみました。
import SwiftUI
struct ContentView: View {
var body: some View {
NavigationView {
List {
Text("あれ?")
Text("声が")
Text("遅れて")
Text("聞こえてるよ")
}
.listBackground(.yellow)
.navigationTitle("Title")
}
}
}
.listBackground(_ color:)
で指定したカラーがNavigationView
の範囲まで反映されます。
UITableView.appearance()の問題点
UITableView.appearance().backgroundColor
を使うと、全てのList
の背景色が変更されます。
例として、最初に黄色のListを表示させて、NavigationBarのボタンを押すと、赤色のListに遷移してみます。
コード
ContentView(Yellow)
import SwiftUI
struct ContentView: View {
var body: some View {
NavigationView {
List {
Text("あれ?")
Text("声が")
Text("遅れて")
Text("聞こえてるよ")
}
.listBackground(.yellow)
.navigationTitle("Yellow")
.toolbar {
ToolbarItem(placement: .navigationBarTrailing) {
NavigationLink {
NextView()
} label: {
Image(systemName: "chevron.right")
}
}
}
}
}
}
NextView(Red)
import SwiftUI
struct NextView: View {
var body: some View {
List {
Text("いいえ")
Text("普通に")
Text("聞こえてるよ")
}
.listBackground(.red)
.navigationTitle("Red")
}
}
結果
最初にNextView
に遷移した際には、List
の色の変化は適用されますが、その色の変化が全てのList
に反映されるので前画面(ContentView)に戻った際に黄色で表示させたいはずのList
が赤色になってしまいました。
ルートビューでListの背景を透明にする方法
それぞれでUITableView.appearance().backgroundColor
を設定すると意図した状態になりませんでした。
これの対策として、まずルートビューでUITableView.appearance().backgroundColor
を透明にしておきます。
import SwiftUI
@main
struct KoeGaOkureteruyoApp: App {
init() {
UITableView.appearance().backgroundColor = .clear
}
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
backgroundにColorを指定する
.listBackground(_ color:)
のコードを削除して、.background
に置き換えます。
ContentView(Yellow)
import SwiftUI
struct ContentView: View {
var body: some View {
NavigationView {
List {
Text("あれ?")
Text("声が")
Text("遅れて")
Text("聞こえてるよ")
}
.background(.yellow) // .backgroundに変更
.navigationTitle("Yellow")
.toolbar {
ToolbarItem(placement: .navigationBarTrailing) {
NavigationLink {
NextView()
} label: {
Image(systemName: "chevron.right")
}
}
}
}
}
}
NextView(Red)
struct NextView: View {
var body: some View {
List {
Text("いいえ")
Text("普通に")
Text("聞こえてるよ")
}
.background(.red) // .backgroundに変更
.navigationTitle("Red")
}
}
結果
それぞれのList
で意図した背景色を確認出来ました。
おわりに
appearance()
を使用すると全てのList
に影響与えてしまうことが変わり、色々と考慮しながら使う必要があることが分かりました。もし、他に良い方法等ありましたら教えていただけると嬉しいです。
いつかSwiftUIだけで容易に背景色が変更できるようになると良いね。