Hide separators in List (SwiftUI)

How do I hide the separation lines inside Lists in SwiftUI for iOS 14?
Previously I could use
Code Block
UITableView.appearance().separatorStyle = .none

but this doesn't seem to work anymore.
  • I had the same problem use this

    init() { UITableView.appearance().separatorColor = .clear }

Add a Comment

Replies

Till the time we have this option available in SwiftUI, we can use [ForEach](https://developer.apple.com/documentation/swiftui/foreach) for hiding the separator.

Code Block Swift
VStack {
      ForEach(permissions) {
        PermissionView(permission: $0)
      }
      .padding(.bottom, 8)
    }


I think the best way I’ve found is this:
Code Block Swift
ScrollView {
LazyVStack(pinnedViews: .sectionHeaders) {
// list content goes here
}
}

The optional pinnedViews parameter can be used to pin the section headers (or footers, or both) to the top of the list - like the PlainListStyle. You will need to, of course, have Sections in the list.
You might need to apply some frame modifiers to the content and some padding to inset it from the edge of the screen.
Still no solution? Hope it will appear soon, please Apple give us this feature 🙏
I'm trying to do the same thing here. Tried UITableView.appearance().separatorStyle = .none in .onAppear() modifier but does not work. Xcode 12.4, iOS 14.0. I remember back in Objective-C time there was this single line on the UITableView that can remove the separators.

Yes, we need Apple to fix this annoying issue in Swift 3.0.

In the meantime, I am using this that seems to work in iOS14.4 and XC 12.4:

VStack { ScrollView { ForEach() } }

Yes, that is right, the ScrollView inside the VStack, also works with LazyVStack, which seems just the opposite than you would think.

The use case here is that the VStack has a small frame and not having the ScrollView and a large number of items will override the frame and cause the VStack to grow beyond the frame, which seems very wrong... another battle for another day.

Hope this helps your frustrations.

Cheers, and get ready for "one last thing"...

Felipe

I have same problem. But I know handmade solution for it. So, if you set List row parameters like

.listRowInsets(EdgeInsets(top: -5, leading: 0, bottom: 0, trailing: 0))

and padding of row view body like

.padding(EdgeInsets(top: Statics.adjustValue(v: 10), leading: Statics.adjustValue(v: 10), bottom: Statics.adjustValue(v: 10), trailing: Statics.adjustValue(v: 10)))

then separator will be hidden.

FOR ALL iOS VERSIONS

Just wanted to tell that this feature is now available in iOS 15

Just wanted to tell that this feature is now available in iOS 15

.listRowSeparator(.hidden)

For iOS13,iOS14,iOS15,and remove the separator at the top of the first cell

Add viewModifier

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)
        )
  }
}

Usage

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())
    }
}

iOS / SwiftUI 技术交流

我创建了一个 微信 iOS 技术交流群、SwiftUI 技术交流群,欢迎小伙伴们加入一起交流学习~

可以加我微信我拉你进去(备注iOS),我的微信号 wr1204607318

This is how I do it. Just match UITableView.appearance().separatorColor and listRowBackground.

struct ContentView: View {
    init(){
        UITableView.appearance().separatorColor = UIColor.white
    }

    struct RowImage: View {
        var id: Int
        var body: some View {
            VStack{
                Text("TEST\(id)")
            }
        }
    }

    var body: some View {
        List (0 ..< 100,id:\.self) { i in
            RowImage(id: i)
                .listRowBackground(Color.white)
        }
}

Just for completion:

This is working for iOS 16 and Xcode 14.3

.listRowSeparator(.hidden)

You need to set it on each row. e.g.:

List(0..<5) { _ in
    PreferenceView()
        .listRowSeparator(.hidden)
 }