44

I've created a simple List as below, but there are extra separators below it.

List {
  Text("Item 1")
  Text("Item 2")
  Text("Item 3")
}

Result:

enter image description here

I've tried embedding the List inside a VStack and adding Spacer() like below code but it's not working properly. It removes about half of the empty cells.

VStack{
  List {
    Text("Item 1")
    Text("Item 2")
    Text("Item 3")
  }
  Spacer()
}

How would I remove these extra separators in SwiftUI?

1
  • 2
    In UIKit you fix this by setting the table view's footerView to an empty view. Maybe SwiftUI supports a List footer. Commented Jun 7, 2019 at 16:59

10 Answers 10

36

iOS 14:

iOS 14 doesn't show extra separators below the list by default and to removing all separators, you need to use a LazyVStack inside a ScrollView instead. (because iOS is NOT supporting appearance for SwiftUI lists anymore).

LazyVStack Preview


iOS 13:

⚠️ This method is deprecated and it's not working from iOS 14

No need for Section or .grouped style!

There is a UITableView behind SwiftUI's List for iOS 13. So to remove

- Extra separators (below the list):

you need a tableFooterView and to remove. Note that iOS 14 doesn't show extra separators below the list by default.

- All separators (including the actual ones):

you need separatorStyle to be .none

init() {
    if #available(iOS 14.0, *) { 
        // iOS 14 doesn't have extra separators below the list by default.
    } else {
        // 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")
    }
}

Note that it eliminates all tables/lists's separators. So you can toggle it in a methods like onAppear() or etc. as you wish.

Sign up to request clarification or add additional context in comments.

3 Comments

At this time, neither "tableFooterView" nor "separatorStyle" is reachable.
For IOS 14, when we used LazyVStack we loose the selection and reordering features of a list. So, it's not a valid solution for all of the cases.
"OS 14 doesn't show extra separators below the list by default." Does this mean there is a way to show separators below the list? Because I have the exact opposite scenario where I would like to to show empty rows.
21

It's not a perfect solution, but you could use a ScrollView, where each cell is created using a ForEach call, and the dividers are created using Divider().

Edit: I spoke with Apple engineers at WWDC about this. They have heard lots of feedback regarding removing/changing dividers. However, for now my above answer is their recommendation.

5 Comments

any hints how to add some nice animation for reloading? when data will change?
@Lifeplus that's a good point. For now, I'd use one of the other answers which uses a List, and the ability to manipulate separators should be added soon.
Not bad solution, but we need to not forgot about "reusable" view (for tableview / list). if we use scrollview as solution, we automatically up memory usage.
Also it's not an option if we need "Edit" functionality. Like ability to delete/move the rows.
@RustamG you're right. Frankly, I'm a little disappointed with the bare minimum customization for standard elements provided by SwiftUI so far. I get that it's new, but if it's the future for Apple platforms, you'd think they'd have a huge push behind it.
18

This is for iOS 13 builds only.

Use onAppear modify a separator style through UITableView and restore to the initial state with onDisappear

List {}
.onAppear { UITableView.appearance().separatorStyle = .none }
.onDisappear { UITableView.appearance().separatorStyle = .singleLine }

Comments

14

Not an ideal solution, but you can make the list style .grouped by .listStyle(.grouped) which removes any empty cells that may come below.

Comments

9

Adding a white rectangle as a footer and with 0 EdgeInsets worked for me:

struct Footer: View {
    var body: some View {
        Rectangle()
            .foregroundColor(.white)
            .listRowInsets(EdgeInsets())
    }
}

struct Timeline : View {
    var body: some View {
        List {
            Section(footer: Footer()) {
                Text("Item 1")
                Text("Item 2")
                Text("Item 3")
            }
        }
    }
}

The only problem is it also adds a Header and I'm not sure how to get rid of it.

enter image description here

Comments

4

iOS 13 builds only:

You can add this, for remove separator.

UITableView.appearance().separatorColor = .clear

1 Comment

this is the only thing that worked for me. Thank you!
2

Here's one way.

List {
         Section(footer: Text(""))) {
                Text("One")
                Text("Two")
                Text("Three")
            }
     }

Instead of the Text view in the footer, you can create your own. Note -I tried EmptyView() but that doesn't actually remove the redundant separators.

2 Comments

Thanks, is there any way to remove the extra dividers this adds to the top and bottom of the list?
As I mentioned you can create own and use it instead of Text, maybe a view with 1 pt height.
2

Two ways of doing that:

struct ContentView: View {
    
    var body: some View {
        
        List {
                Text("One")
                Text("Two")
                Text("Three")
        }.listStyle(GroupedListStyle())
    }
}
struct ContentView: View {
    
    var body: some View {
        
        List {
            Section(header: Text("Header"), footer: Text("Footer")) {
                Text("One")
                Text("Two")
                Text("Three")
            }
        }
    }
}

I recommend grouped list style.

Comments

0

Try this, if you want to use the section, There's still a footer visible with this:

List {
    Section(footer: Text("")) {
        Text("My text")
    }
    EmptyView()
}

enter image description here

I came up with a hacky way to hide footer in case you don't have any section:

List {
    Text("Item 1")
    Text("Item 2")

    // Adding empty section with footer
    Section(footer:
        Rectangle()
            .foregroundColor(.clear)
            .background(Color(.systemBackground))){EmptyView()}
            .padding(.horizontal, -15)
}

enter image description here

Comments

0

For unknown reason, I had this problem in tableView even after iOS14, even though the answer above that there will be no longer extra separator lines in default.

The method I use to solve it is to set footerView to vacant UIView, as in that same answer.

your_tableView.tableFooterView = UIView()

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.