🍎

SwiftUIのListで `.listRowBackground()` を指定してもセルの背景色が反映されたり反映されなかったりする問題

2022/05/09に公開

SwiftUI の Listで .listRowBackground() を指定してもセルの背景色が反映されたり反映されなかったりする問題が発生していた。

国内外のTips記事では単にセルの背景色を変更する方法しか紹介されておらず、この問題を取り扱っているところはなくて途方に暮れていた。問題に気付いてから 4,5ヶ月 悩んだが、ようやく集中して問題解決に取り掛かる時間ができたので調査した。

.listRowBackground() を指定してもセルの背景色が反映されたり反映されなかったりする

SwiftUIのListでセルの背景色をつける場合、下記のように .listRowBackground(Color.red) を指定することでセルの背景色を設定することができる。

import SwiftUI

struct ContentView: View {

    var body: some View {
        List{
            Text("背景は赤色です")
                .listRowBackground(Color.red)
        }
    }
}

.listRowBackground() を使って背景色を指定しているのにも関わらず、特定のアプリでは背景色が反映されたり反映されなかったりする。リストをスクロールした際に背景色がマチマチになってしまい、表示が安定しない問題が発生しており頭を抱えていた。

iOS 13ではあまり発生しなく、iOS 14ではよく発生する、iOS 15ではあまり発生しないとiOSバージョンによっても発生頻度がまちまちであった。iOS 15でも発生していることから「SwiftUIを使っているから古いiOSバージョンではうまく動かないんですよ」と言い訳することもできなかった。

解決編

問題が発生しないアプリとの差分を取っていったところ、問題の発生しているアプリには起動時に下記のようなコードがあった。

let selectedView = UIView()
selectedView.backgroundColor = UIColor.yellow
UITableViewCell.appearance().selectedBackgroundView = selectedView

UITableViewCell.appearance().selectedBackgroundView を設定している箇所をコメントアウトしたことで .listRowBackground(Color.red) の処理が正しく動くようになった。

このことから裏付けは取れないが現象から鑑みるに、.listRowBackground() を使った背景色の設定と appearance で指定された背景色の設定 が重複してしまい、タイミングによって後者の設定が有効になってしまっていたと思われる。それぞれに明確に異なる背景色を設定していればすぐに気付いたかもしれないが、同じグレー系統の少し異なる背景色だったため発見が遅れてしまった。

Discussion