📱

[iOS16対応]SwiftUIのListの全体の背景を変える方法

2022/07/03に公開

この記事の対象者

  • Listの背景色を変えたい
    任意の色を下記実装に当てはめて実装を行なってください
  • ZStackを用いて背景に画像やグラデーションなどを設定したい
    backgroundColor.clearを設定してください。
    背景が透明になってZStackのList以前に記述した要素が見えるようになります。

iOS16ではListの実装でUITableViewは使用しません

The implementation of list no longer uses UITableView.

(引用:iOS & iPadOS 16 Beta 2 Release Notes)
https://developer.apple.com/documentation/ios-ipados-release-notes/ios-ipados-16-release-notes
要約すると見出しの通りです。
今まではUITableViewと紐づけられていたためSwiftUIでは賄いきれない機能の実装は

init() {
	UITableView.appearance().backgroundColor = .orange
}

といった形でUITableViewに変更を加えて実装していました。

しかしiOS16からはUICollectionViewを使用することになったため記述を変更する必要があります。

Tips:実装する前に

まずはありがちな疑問を解消しておきます。
UITableViewからUICollectionViewに変わったので

init() {
	UICollectionView.appearance().backgroundColor = .orange
}

に直しちゃえば変わるのでは?と思う方もいると思いますが変わりません。。。
この記述で実装できるようextensionを作成していきます。

UICollectionViewのextension(拡張)を作成する

extension UICollectionReusableView {
    override open var backgroundColor: UIColor? {
        get { .clear }
        set { }
    }
}

上記のextensionをContentViewのトップレベルに追記します。
.clearはデフォルト値として適当に入れているため直接的には影響しませんので気にしなくて大丈夫です。
この段階では区切り線は透明になります。
背景色と揃えたい方は下記手順に従ってください。

※区切り線を背景色にしたい場合

区切り線を背景と同色にしたい場合はextensionのset{ }を下記の記述に書き換えてください

set { super.backgroundColor = .orange } //好きな色

この記述で背景と区切り線の色の実装は終了です。
以降の手順は行わなくて大丈夫ですのでプレビューorビルドで確認してください。

サンプルコード(区切り線色指定用)
import SwiftUI

struct ContentView: View {
    var body: some View {
        List{
            Section("sample"){
                Text("A")
                Text("B")
            }
        }
    }
}

extension UICollectionReusableView {
    override open var backgroundColor: UIColor? {
        get { .clear }
        set { super.backgroundColor = .orange}
    }
}

init()を記述する

init() {
        UICollectionView.appearance().backgroundColor = .orange  //好きな色
}

init()をContentView内に記述すれば以上で背景色の変更は終了です。

サンプルコード(区切り線なし)
import SwiftUI

struct ContentView: View {
    
    init() {
        UICollectionView.appearance().backgroundColor = .orange
    }
    
    var body: some View {
        List{
            Section("sample"){
                Text("A")
                Text("B")
            }
        }
    }
}

extension UICollectionReusableView {
    override open var backgroundColor: UIColor? {
        get { .clear }
        set { }
    }
}

まとめ

実装できたでしょうか?
区切り線まで変わってしまうというのは少し不便ですが背景色をどうしても変えたいという方は実装してください。
様々な開発者の中で他の方法はないのか色々を模索されているようですので今後より実装しやすい形へとアップデートされていく可能性があるのでその際はコメント欄などで共有していただけると幸いです!

参考

https://stackoverflow.com/questions/72649907/ios-16-swiftui-list-background#

Discussion