Reputation: 559
I'm trying to remove the "row" separators (known as dividers in SwiftUI) from a List
in SwiftUI.
I went through the List
documentation, but I haven't been able to find a modifier for that.
Any help would be appreciated.
Upvotes: 51
Views: 22385
Reputation: 79
extension View {
/// 隐藏 List 中的 分割线
func hideRowSeparator(insets: EdgeInsets = .init(top: 0, leading: 0, bottom: 0, trailing: 0),
background: Color = .white) -> some View {
modifier(HideRowSeparatorModifier(insets: insets, background: background))
}
}
struct HideRowSeparatorModifier: ViewModifier {
static let defaultListRowHeight: CGFloat = 44
var insets: EdgeInsets
var background: Color
init(insets: EdgeInsets, background: Color) {
self.insets = insets
var alpha: CGFloat = 0
if #available(iOS 14.0, *) {
UIColor(background).getWhite(nil, alpha: &alpha)
assert(alpha == 1, "Setting background to a non-opaque color will result in separators remaining visible.")
}
self.background = background
}
func body(content: Content) -> some View {
content
.padding(insets)
.frame(minWidth: 0, maxWidth: .infinity, minHeight: Self.defaultListRowHeight)
.listRowInsets(EdgeInsets())
.overlay(
VStack {
HStack {}
.frame(maxWidth: .infinity)
.frame(height: 1)
.background(background)
Spacer()
HStack {}
.frame(maxWidth: .infinity)
.frame(height: 1)
.background(background)
}
.padding(.top, -1)
)
}
}
struct ContentView: View {
var body: some View {
List {
ForEach(0 ..< 30) { item in
HStack(alignment: .center, spacing: 30) {
Text("Hello, world!:\(item)").padding()
}
.hideRowSeparator(background: .white)
}
}
.listStyle(PlainListStyle())
}
}
https://github.com/wangrui460/HiddenListLine4SwiftUI
我创建了一个 微信 iOS 技术交流群、SwiftUI 技术交流群,欢迎小伙伴们加入一起交流学习~
可以加我微信我拉你进去(备注iOS),我的微信号 wr1204607318
Upvotes: 1
Reputation: 119128
This year Apple introduced a new modifier .listRowSeparator
that can be used to style the separators. you can pass .hidden
to hide it:
List {
ForEach(items, id:\.self) {
Text("Row \($0)")
.listRowSeparator(.hidden)
}
}
Apple introduced LazyVStack
In iOS 14. you may consider using it instead of list for this:
ScrollView {
LazyVStack {
ForEach((1...100), id: \.self) {
Text("Placeholder \($0)")
}
}
}
Keep in mind that LazyVStack
is lazy and doesn't render all rows all the time. So they are very performant and suggested by Apple itself in WWDC 2020.
There is a UITableView
behind SwiftUI's List
for iOS. So to remove
you need a tableFooterView
and to remove
you need separatorStyle
to be .none
init() {
// To remove only extra separators below the list:
UITableView.appearance().tableFooterView = UIView()
// To remove all separators including the actual ones:
UITableView.appearance().separatorStyle = .none
}
var body: some View {
List {
Text("Item 1")
Text("Item 2")
Text("Item 3")
}
}
Upvotes: 32
Reputation: 77
From: Swiftui Views Mastery Book SwiftUI 2.0 Mark Moeykens
.listStyle(SidebarListStyle()) # IOS 14
You can apply this new list style which will remove the separator lines.
Upvotes: 5
Reputation: 7687
See existing answers using UITableView.appearance()
.
⚠️ Be aware that in the iOS 14 SDK, List
does not appear to be backed by UITableView
. See the alternate solution below:
I do have a pure SwiftUI solution for iOS 14, but who knows how long it's going to continue working for. It relies on your content being the same size (or larger) than the default list row and having an opaque background.
⚠️ This does not work for iOS 13 builds.
Tested in Xcode 12 beta 1:
yourRowContent
.padding(EdgeInsets(top: 0, leading: 16, bottom: 0, trailing: 16))
.frame(
minWidth: 0, maxWidth: .infinity,
minHeight: 44,
alignment: .leading
)
.listRowInsets(EdgeInsets())
.background(Color.white)
Or if you're looking for a reusable ViewModifier
:
import SwiftUI
struct HideRowSeparatorModifier: ViewModifier {
static let defaultListRowHeight: CGFloat = 44
var insets: EdgeInsets
var background: Color
init(insets: EdgeInsets, background: Color) {
self.insets = insets
var alpha: CGFloat = 0
UIColor(background).getWhite(nil, alpha: &alpha)
assert(alpha == 1, "Setting background to a non-opaque color will result in separators remaining visible.")
self.background = background
}
func body(content: Content) -> some View {
content
.padding(insets)
.frame(
minWidth: 0, maxWidth: .infinity,
minHeight: Self.defaultListRowHeight,
alignment: .leading
)
.listRowInsets(EdgeInsets())
.background(background)
}
}
extension EdgeInsets {
static let defaultListRowInsets = Self(top: 0, leading: 16, bottom: 0, trailing: 16)
}
extension View {
func hideRowSeparator(
insets: EdgeInsets = .defaultListRowInsets,
background: Color = .white
) -> some View {
modifier(HideRowSeparatorModifier(
insets: insets,
background: background
))
}
}
struct HideRowSeparator_Previews: PreviewProvider {
static var previews: some View {
List {
ForEach(0..<10) { _ in
Text("Text")
.hideRowSeparator()
}
}
.previewLayout(.sizeThatFits)
}
}
Upvotes: 5
Reputation: 125
Adding UITableView.appearance().separatorColor = .clear
for initializer
struct SomeView: View {
init() {
UITableView.appearance().separatorColor = .clear
}
}
I hope you to resolve this problem.
Upvotes: 6
Reputation: 22846
The current workaround is to remove them via UIAppearance
:
UITableView.appearance(whenContainedInInstancesOf:
[UIHostingController<ContentView>.self]
).separatorStyle = .none
Upvotes: 6
Reputation: 2498
while this solution works correctly let's clean up the work using
ViewModifier
public struct ListSeparatorStyleNoneModifier: ViewModifier {
public func body(content: Content) -> some View {
content.onAppear {
UITableView.appearance().separatorStyle = .none
}.onDisappear {
UITableView.appearance().separatorStyle = .singleLine
}
}
}
now let's make a small extension that would help to hide the details
extension View {
public func listSeparatorStyleNone() -> some View {
modifier(ListSeparatorStyleNoneModifier())
}
}
As you can see, we’ve wrapped our appearance setting code into a neat little view modifier. you can declare it directly now
List {
Text("1")
Text("2")
Text("3")
}.listSeparatorStyleNone()
Upvotes: 14
Reputation: 4226
You may use ForEach
within a ScrollView
instead of List
for dynamic views without any styling
Upvotes: 10