SwiftUIの List
はデフォルトでセパレータ(区切り線)が表示されていて、非表示にすることができません。
iOS13
iOS13では、以下のどちらかの方法で消すことができます。
UITableView
のappearanceを変更する
List { ListItem(title: "タイトル1") ListItem(title: "タイトル2") ListItem(title: "タイトル3") ListItem(title: "タイトル4") } .onAppear { UITableView.appearance().separatorStyle = .none } .onDisappear { UITableView.appearance().separatorStyle = .singleLine }
こんなかんじで onAppear
と onDisappear
で separatorStyle
を切り替えることで消すことができます。
注意点としては、アプリ全体の設定が変わるので、全ての List
や UITableView
が影響を受けます。
Introspect を使う
List { ListItem(title: "タイトル1") ListItem(title: "タイトル2") ListItem(title: "タイトル3") ListItem(title: "タイトル4") } .introspectTableView { tableView in tableView.separatorStyle = .none tableView.tableFooterView = .init() }
Introspectで UITableView
にアクセスできるので、 separatorStyle
を設定できます。
iOS14
iOS14ではiOS13の方法どちらを使っても消すことはできません。
listRowInsets
と background
を使う
各 ListItem
に対し、
ListItem(title: "タイトル1") .listRowInsets(.init(top: -1, leading: 0, bottom: -1, trailing: 0)) .background(bgColor)
とすると一応消せます。ViewModifierで書くとこんなかんじ。
struct RemoveSeparatorModifier: ViewModifier { let bgColor: Color func body(content: Content) -> some View { content .listRowInsets(.init(top: -1, leading: 0, bottom: -1, trailing: 0)) .background(bgColor) } } extension View { func removeSeparator(bgColor: Color = .white) -> some View { modifier(RemoveSeparatorModifier(bgColor: bgColor)) } }
ListItem(title: "タイトル1") . removeSeparator()
この実装には以下のような問題があります。
- デフォルトのinsetsを上書きするので、別途レイアウトが必要。
- bgColorで覆うので、タップ時にセルハイライトされない。ハイライトが必要な場合は別途実装が必要。
- Sectionとか使う場合にはさらに調整が必要。
LazyVStackを使う
LazyVStack
が使える場合は LazyVStack
を使った方が幸せになれます。