LoginSignup
0
0

iOS14環境でListの罫線が欠ける問題の解消方法

Posted at

はじめに

iOS14環境でListを使用するとコンテンツの下に置いた罫線のうち、何箇所かがレンダリング時に消えてしまう問題が発生。チームの開発メンバーに解決方法をお聞きしたので、備忘録として記載。

結論

少々トリッキーだが、Listのアイテムの上に置くことで解決する

サンプルコードは以下の通り

import SwiftUI

struct TextData: Identifiable {
    var id: String {
        text
    }
    // textは一意であるとする
    var text: String
}

struct ContentView: View {
    // サンプルデータ
    let textDataList: [TextData] = [.init(text: "test1"), .init(text: "text2"), .init(text: "text3")]

    var body: some View {
        List {
            ForEach(textDataList, content: listContent)
                .listRowSeparatorHidden()
                .listRowInsets(.init())
                .listRowBackground(Color(.white))
        }
        .listStyle(.plain)
    }

    private func listContent(textData: TextData) -> some View {
        VStack(spacing: 10) {
            // 上に置くことで解決する
            divider

            HStack(spacing: 0) {
                Text(textData.text)

                Spacer()

                Image(systemName: "chevron.right")
            }

            // 最後のアイテムの下の罫線の表示ロジック
            if textData.id == textDataList.last?.id {
                divider
            }
        }
    }

    private var divider: some View {
        Divider()
            .background(Color(.gray))
            .frame(maxWidth: .infinity)
    }
}

extension View {
    // iOS14番台でListのデフォルトの罫線を非表示にするextension
    // .listRowSeparator(.hidden)が使えないため
    func listRowSeparatorHidden() -> some View {
        frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .leading)
            .listRowInsets(.init(top: -1, leading: -1, bottom: -1, trailing: -1))
            .background(Color(UIColor.systemBackground))
    }
}

これで解決と思いきや...

今度はiOS15環境で罫線が欠ける問題が発生..

そのため、バージョンで分岐をする。バージョン分岐を加えたコードがこちら。

import SwiftUI

struct TextData: Identifiable {
    var id: String {
        text
    }
    // textは一意であるとする
    var text: String
}

struct ContentView: View {
    // サンプルデータ
    let textDataList: [TextData] = [.init(text: "test1"), .init(text: "text2"), .init(text: "text3")]

    var body: some View {
        List {
            if #available(iOS 15.0, *) {
                ForEach(textDataList, content: listContentIOS15)
                    .listRowSeparator(.hidden)
                    .listRowInsets(.init())
                    .listRowBackground(Color(.white))

            } else {
                ForEach(textDataList, content: listContent)
                    .listRowSeparatorHidden()
                    .listRowInsets(.init())
                    .listRowBackground(Color(.white))
            }
        }
        .listStyle(.plain)
    }

    private func listContentIOS15(textData: TextData) -> some View {
        VStack(spacing: 10) {
            HStack(spacing: 0) {
                Text(textData.text)

                Spacer()

                Image(systemName: "chevron.right")
            }

            // iOS15.0では通常通り下に罫線を置く
            divider
        }
    }

    private func listContent(textData: TextData) -> some View {
        VStack(spacing: 10) {
            // 上に置くことで解決する
            divider

            HStack(spacing: 0) {
                Text(textData.text)

                Spacer()

                Image(systemName: "chevron.right")
            }

            // 最後のアイテムの下の罫線の表示ロジック
            if textData.id == textDataList.last?.id {
                divider
            }
        }
    }

    private var divider: some View {
        Divider()
            .background(Color(.gray))
            .frame(maxWidth: .infinity)
    }
}

extension View {
    // iOS14番台でListのデフォルトの罫線を非表示にするextension
    // .listRowSeparator(.hidden)が使えないため
    func listRowSeparatorHidden() -> some View {
        frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .leading)
            .listRowInsets(.init(top: -1, leading: -1, bottom: -1, trailing: -1))
            .background(Color(UIColor.systemBackground))
    }
}

結論

iOS14はSwiftUIが導入されて間もない時にリリースされたバージョンなので、他にも色々バグが見つかっており、その度に頭を悩ませています。他にもあれば、その都度共有させていただきます。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0