How to remove List Separator lines in SwiftUI 2.0 in iOS 14 and above

15,155

Solution 1

Here is a demo of possible solution. Tested with Xcode 12b.

demo

List {
    ForEach(0..<3) { _ in
        VStack {
            Text("Hello, World!").padding(.leading)
        }
        .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .leading)
        .listRowInsets(EdgeInsets())
        .background(Color(UIColor.systemBackground)))
    }
}

backup

Solution 2

How I made a list that works on both iOS 14 and iOS 13, It shows no separators and extra margins

struct NoButtonStyle: ButtonStyle {
    func makeBody(configuration: Self.Configuration) -> some View {
        configuration.label
    }
}

struct ListWithoutSepatorsAndMargins<Content: View>: View {
        let content: () -> Content
    
        var body: some View {
            if #available(iOS 14.0, *) {
                ScrollView {
                    LazyVStack(spacing: 0) {
                        self.content()
                    }
                    .buttonStyle(NoButtonStyle())
                }
            } else {
                List {
                    self.content()
                }
                .listStyle(PlainListStyle())
                .buttonStyle(NoButtonStyle())
            }
        }
    }

Sample Usage -

ListWithoutSepatorsAndMargins {
    ForEach(0..<5) { _ in
      Text("Content")
    }
}

in case you've more components in list, wrap them in Group

                ListWithoutSepatorsAndMargins {
                    Group {
                            self.groupSearchResults()
                            self.myGroups()
                            self.exploreGroups()
                        }
                    }
                }

    

Hope this helps someone, I wasted a lot of time in such minor thing, Apple is trying to push us hard to use LazyVStack, it seems

Solution 3

Merged @asperi, @akmin and @zrfrank answer into one thing. In my experience List is more reliable and efficient than LazyVStack, so I use still use List for anything complex requiring reliability.

extension View {
    func listRow() -> some View {
        self.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .leading)
            .listRowInsets(EdgeInsets(top: -1, leading: -1, bottom: -1, trailing: -1))
            .background(Color(.systemBackground))
    }
}

List {
    Color.red
         .listRow()


    Color.green
         .listRow()
}

Solution 4

I found this simple solution on the Apple Developer forums. It's working for me on 14.4:

List {
   ...
}.listStyle(SidebarListStyle())

This seems to add a tiny bit of padding around the edges. If that's a problem for you, you could try some negative padding.

Solution 5

iOS 15:

This year Apple introduced a new modifier .listRowSeparator that can be used to style the separators. you can pass .hidden to hide it:

List(items, id:\.self) {
    Text("Row \($0)")
        .listRowSeparator(.hidden)
}

🌈 Also you can set each separator to any color by settings listRowSeparatorTintColor as I mentioned here in this answer:

Demo

iOS 14

Follow the answer here

Share:
15,155
Osama Naeem
Author by

Osama Naeem

Updated on June 03, 2022

Comments

  • Osama Naeem
    Osama Naeem about 2 years

    So the question is pretty simple and it's in the title. I want to remove the line separator in SwiftUI iOS 14. Previously, I was using UITableView().appearance().separatorStyle = .none and that used to do the job in iOS 13. Now however, it doesn't work. Any update or idea on how to make it work. Thanks:)

    • Asperi
      Asperi about 4 years
      Well, there is no more UITableView underneath... no more hucks ))
    • Jordan H
      Jordan H almost 4 years
      @SchmidtyApps posted a solution that I've confirmed works! But the answer was deleted by a moderator and I can't undelete it. See github.com/SchmidtyApps/SwiftUIListSeparator
    • Petar
      Petar over 2 years
      @Asperi what do you mean there is no more UITableView underneath - there is one still
  • akmin
    akmin about 4 years
    Use Color(UIColor.systemBackground)) instead of Color.white?
  • zrfrank
    zrfrank almost 4 years
    In addition, you may want to apply negative edge insets in some cases. .listRowInsets(EdgeInsets(.init(top: -1, leading: -1, bottom: -1, trailing: -1))).
  • Jordan H
    Jordan H almost 4 years
    How can you do this without modifying the insets? Removing all the padding makes the list look bad.
  • Vivienne Fosh
    Vivienne Fosh over 3 years
    this solution is harmful, because LazyVStack works with cells in a completely different manner, than List. You can check CPU load when scrolling those cells. If the cell is something more than Text(“hello test”), you will see peak load while scrolling
  • Harish saini
    Harish saini over 3 years
    CPU usage goes up a bit while scrolling but comes back down instantly as things stabilize, which used to happen in UITableView as well, I have pretty heavy cells in my app and very big lists, It has never caused a lag in scrolling or crash for us, we saw no issues so far but use at your own risk!
  • Zapko
    Zapko over 3 years
    @Lonkly why do you think it can be a problem?
  • Vivienne Fosh
    Vivienne Fosh over 3 years
    @Zapko how do you think, what is the main difference between StackView and TableView in UIKit? The same, that List and LazyVStack have. TableView reuses cells, LazyVStack does not. So when you have more elements that fit the screen, and the layout is more complex than Text("Content") you will get extreme slowness and lags. Therefore providing the solution that is called ListWithoutSeparators{} and making it a LazyVStack inside is super harmful.
  • pawello2222
    pawello2222 over 3 years
    @JordanH You can set the list style to .listStyle(InsetListStyle())
  • Yiming Dong
    Yiming Dong over 3 years
    LazyVStack doesn't fit if you want to have list sections.
  • Brownsoo Han
    Brownsoo Han over 3 years
    This works for me. List + some View (not LazyVStack)
  • Qingwan Kuah
    Qingwan Kuah over 3 years
    love this solution and it's working beautifully on simulator (XCode 12, running iOS 13 and 14) however, it doesn't work on my actual device (iPhone XS, iOS 14.2). The list separators are all showing up for some strange reason. Anyone else faced the same?
  • phuongzzz
    phuongzzz over 3 years
    I think it's the best solution right now, very elegant!
  • Ovi Trif
    Ovi Trif over 3 years
    And where are we supposed to find SceneDelegate?
  • Harish saini
    Harish saini over 3 years
    add it on the launch of your app, the first piece of code that gets executed
  • Harish saini
    Harish saini over 3 years
    in later versions of ios I am getting a default spacing between cells which can be removed by doing the following
  • Harish saini
    Harish saini over 3 years
    List { self.content() .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .center) .listRowInsets(EdgeInsets()) .background(Color.white) } .listStyle(PlainListStyle()) .buttonStyle(NoButtonStyle()) .environment(\.defaultMinListRowHeight, 1)
  • Harish saini
    Harish saini over 3 years
    the extra .environment(\.defaultMinListRowHeight, 1) from the previous solution
  • Shengchalover
    Shengchalover about 3 years
    by using lazy vstack you lose other List benefits like edit state, swipe to delete gesture etc.
  • Harish saini
    Harish saini about 3 years
    I have solved it using List here stackoverflow.com/a/64028051/14327378, please check it out if you want List :)
  • Tulon
    Tulon almost 3 years
    I use button in my list cell. After adding this the highlighted color has gone from my buttons.
  • Posa
    Posa almost 3 years
    On iOS 14 it works like a charm! No LazyVStack but only List + view. Thanks man! I was gettin' mad!
  • Petar
    Petar over 2 years
    What if you actually need to use .listRowInsets with non-zero values for insets ?
  • Robert Atkins
    Robert Atkins over 2 years
    I'm horrified that this works for iOS 14 and seems to do nothing on iOS 15, but that's the way it plays out.
  • Michał Ziobro
    Michał Ziobro over 2 years
    sometimes works, sometimes doesnt'
  • Alec.
    Alec. over 2 years
    Downvoted as this doesn't actually answer the question of how to do it in SwiftUI 2.0 on iOS 14