NRIネットコム Blog

NRIネットコム社員が様々な視点で、日々の気づきやナレッジを発信するメディアです

【SwiftUI】iOS16でTextEditorやListなどの背景色を変更する

概要

iOS16未満ではUITextView.appearance().backgroundColorを使用することでTextEditorやListなどの背景色を変更する事ができました。
しかしiOS16では上記の実装では背景色がを変更する事ができなくなりました。
その代わり、新しく追加されたscrollContentBackgroundを使用する事で背景色を変更する事ができるようになりました。
今記事では上記を踏まえた上でiOS16未満とiOS16からに対応した背景書の変更方法について紹介したいと思います。

環境

この記事は以下のバージョン環境のもと作成されたものです。
【Xcode】14.0
【iOS】16.0
【macOS】Monterey バージョン 12.5

iOS16未満での実装

UITextView.appearance().backgroundColorを使用する事で背景色を変更する事ができます。
init時はclearとしてbackgroundで色を指定しています。

struct HogeView: View {
    @State private var text = ""
    let deviceOS: String
    init() {
        deviceOS = UIDevice.current.systemVersion
        UITextView.appearance().backgroundColor = .clear
    }
    var body: some View {
        ZStack {
            Color.red
                .ignoresSafeArea()
            VStack {
                Text(deviceOS)
                TextEditor(text: $text)
                    .frame(height: 400)
                    .background {
                        Color.blue
                        Rectangle()
                            .stroke(lineWidth: 2)
                    }
                    .padding()
            }
        }
    }
}

iOS16からの実装

上記のコードをそのままiOS16でビルドすると以下のように背景色が変更されません。

iOS16からはscrollContentBackgroundを使用すると変更する事ができます。
scrollContentBackgroundはドキュメントに「このビュー内のスクロール可能なビューの背景の可視性を指定します。」とあり、ListViewやScrollViewの背景もこちらで変更する事を可能にします。
(引用元:https://developer.apple.com/documentation/swiftui/text/scrollcontentbackground(_:)))

使用方法は以下の通りです。

struct HogeView: View {
    @State private var text = ""
    let deviceOS: String
    init() {
        deviceOS = UIDevice.current.systemVersion
    }
    var body: some View {
        ZStack {
            Color.red
                .ignoresSafeArea()
            VStack {
                Text(deviceOS)
                TextEditor(text: $text)
                    .scrollContentBackground(Visibility.hidden)
                    .frame(height: 400)
                    .background {
                        Color.yellow
                        Rectangle()
                            .stroke(lineWidth: 2)
                    }
                    .padding()
            }
        }
    }
}

OS毎に表示制御を行う

各OS毎の実装方法については上記の通りですが、実際UserがどのOSを使用しているかわからないので両方に対応する為に#availableを使用してOSによって返す処理を変更します。

struct HogeView: View {
    @State private var text = ""
    let deviceOS: String
    init() {
        deviceOS = UIDevice.current.systemVersion
        UITextView.appearance().backgroundColor = .clear
    }
    var body: some View {
        ZStack {
            Color.red
                .ignoresSafeArea()
            VStack {
                Text(deviceOS)
                if #available(iOS 16.0, *) {
                    TextEditor(text: $text)
                        .scrollContentBackground(Visibility.hidden)
                        .frame(height: 400)
                        .background {
                            Color.yellow
                            Rectangle()
                                .stroke(lineWidth: 2)
                        }
                        .padding()
                } else {
                    TextEditor(text: $text)
                        .frame(height: 400)
                        .background {
                            Color.blue
                            Rectangle()
                                .stroke(lineWidth: 2)
                        }
                        .padding()
                }
            }
        }
    }
}

これでどちらも対応できます!

Listの場合

最後にiOS16のみですがListの場合も確認しておきます。
OS毎に対応する場合は上記のサンプルコードを参考にして下さい。

var body: some View {
    ZStack {
        Color.red
            .ignoresSafeArea()
        List {
            ForEach(1..<10) { index in
                Text("index: \(index)")
            }

        }
        .scrollContentBackground(Visibility.hidden)
    }
}

まとめ

ようやくSwiftUIのmodifierで背景色を変更できる様になりました!ますます発展していく事を願ってます。

執筆者岡優志

iOSエンジニア
iOSを専門とし、モバイルアプリの開発を行なっています。

Twitter