SwiftUIではUITableViewのような振る舞いを持つViewにList
が存在します。
このListはなかなか曲者でiOS13とiOS14ではデザインの設定方法が異なり、なかなか思うように扱うことが出来ません。
iOS14からは遅延読み込みが可能なLazyVStackが登場しているのでこちらを代替手段として用いるのが簡単です。
ということで、OSのバージョンでListとLazyVStackの出し分けをしつつ似たような見た目の振る舞いを持つViewを作成してみます。
struct TableView<Content: View>: View {
let content: () -> Content
let rowBackgroundColor: Color
init(rowBackgroundColor: Color, _ content: @escaping () -> Content) {
self.content = content
self.rowBackgroundColor = rowBackgroundColor
UITableView.appearance().separatorStyle = .none // この区切り線を消すコードはiOS13でのみ有効
UITableView.appearance().backgroundColor = .clear
}
var body: some View {
if #available(iOS 14, *) {
ScrollView {
LazyVStack(spacing: 0) {
self.content()
.background(self.rowBackgroundColor)
}
}
} else {
List {
self.content()
.listRowInsets(EdgeInsets())
.listRowBackground(self.rowBackgroundColor)
}
.environment(\.defaultMinListRowHeight, 0)
}
}
}
このViewは以下のように利用することで、似たような振る舞いをもたせることが可能です。
struct ContentView: View {
var body: some View {
TableView(rowBackgroundColor: .blue) {
ForEach(0..<100) { index in
Group {
HStack {
Circle()
.frame(width: 50, height: 50)
Text("No, \(index)")
Spacer()
}
.padding(.vertical, 12)
.padding(.horizontal, 20)
}
}
}
.background(Color.blue.edgesIgnoringSafeArea(.all))
}
}