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'm having same issue. I'm using macOS Catalina, Xcode 12 beta.
I'm having same issue. I'm using macOS 11.6 beta, Xcode 12 beta.
StackOverflow post suggested something super tacky, would rather not do this.

SwiftUI team, please just give us a ".listSeparatorStyle(.none)" view modifier.
Same issue here. Have tried everything I can think of - I was really hoping that SwiftUI 2.0 would bring more flexibility for Lists with custom style, not remove existing customization.
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.

Tested in Xcode 12 beta 1:

Code Block swift
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:

Code Block swift
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)
  }
}


I used this code to hide the separators, but it's a poor workaround:

Code Block
.padding(EdgeInsets(top: 10, leading: 16, bottom: 10, trailing: 16))
.listRowInsets(EdgeInsets())
.background(Color("BackColor"))

But I'd like a ".listSeparatorStyle(.none)" view modifier for sure -- anyone file a radar I can reference in my own feedback?
  • - UPDATE: my radar feedback on this: FB7836043

Submitted FB7999069. I really hope they give us some APIs to control separators in the future iOS 14 Beta.
The answers here no longer work for Xcode 12 Beta 4 - has anyone else found a new solution?
Same thing. Man SwiftUI is awesome, I can build screens and components really fast but spend even more time on the most basic stuff like trying to hide a darn line separator. Very frustrating.
Wait 2 years and SwiftUI will have most of UIKit and other's capabilities.
I also submitted feedback. Apple we need this .listSeparatorStyle(.none).
Radar #FB8654253
I created a project to solve this issue. See post on SO here:

https://stackoverflow.com/a/63909310/2804699
using:

.listStyle(SidebarListStyle())

should be all you need. But you meed to use negative padding or other tricks as this style has bit more spacing from all sides then the old version
If I can't remove such a simple thing like a damn separator, why I should use this framework? To spend hours finding a solution? All of the mentioned workarounds doesn't work anymore.
This basic feature is very much needed SwiftUI team.
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

I had the same problem use this

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

Hide separators in List (SwiftUI)
 
 
Q