UITableView
iOS development
iOS
Swift
UITableViewCell

delete lines between UITableViewCells in UITableView

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

The lines between UITableViewCell rows are controlled by the table view's separator configuration. If you want to remove them, the usual solution is to change the table view's separatorStyle. If you only want to hide separators in certain situations, you also need to understand empty cells, insets, and custom cell styling.

Remove All Cell Separators

The direct way to remove the built-in lines is to set separatorStyle to .none.

swift
1import UIKit
2
3final class ItemsViewController: UITableViewController {
4    override func viewDidLoad() {
5        super.viewDidLoad()
6        tableView.separatorStyle = .none
7    }
8}

This removes the default separator lines between visible cells. If your goal is simply "no lines anywhere," this is usually enough.

Distinguish Real Cell Separators from Empty-Row Lines

A common source of confusion is that developers remove the normal separators but still see lines below their actual data. Those often come from empty table rows rather than your populated cells.

The standard fix is to provide an empty footer view:

swift
1override func viewDidLoad() {
2    super.viewDidLoad()
3    tableView.separatorStyle = .none
4    tableView.tableFooterView = UIView(frame: .zero)
5}

That tells the table view not to render the default empty-row separators after your content ends.

Adjust Instead of Removing When Needed

Sometimes you do not want to delete separators completely. You may only want to shorten them, indent them, or hide them for selected rows. In that case, separator insets and custom cell layout are often better than disabling the feature globally.

For example:

swift
1override func viewDidLoad() {
2    super.viewDidLoad()
3    tableView.separatorInset = UIEdgeInsets(top: 0, left: 20, bottom: 0, right: 20)
4}

This keeps separators but changes how they appear. That can preserve visual grouping without the full-width default look.

Use Custom Drawing for Full Control

If the built-in separators are not flexible enough, another option is to hide them and draw your own divider inside the cell. This is common when you want custom colors, margins, or rules such as "no separator after the last item in a section."

swift
1final class ItemCell: UITableViewCell {
2    private let customSeparator: UIView = {
3        let view = UIView()
4        view.backgroundColor = .lightGray
5        view.translatesAutoresizingMaskIntoConstraints = false
6        return view
7    }()
8
9    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
10        super.init(style: style, reuseIdentifier: reuseIdentifier)
11        contentView.addSubview(customSeparator)
12
13        NSLayoutConstraint.activate([
14            customSeparator.heightAnchor.constraint(equalToConstant: 1),
15            customSeparator.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 16),
16            customSeparator.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -16),
17            customSeparator.bottomAnchor.constraint(equalTo: contentView.bottomAnchor)
18        ])
19    }
20
21    required init?(coder: NSCoder) {
22        fatalError("init(coder:) has not been implemented")
23    }
24}

This takes more work, but it gives complete control over the appearance.

Consider the Table Style

Grouped, inset-grouped, and plain tables already look different, and separator visibility interacts with those styles. In some designs, removing separators entirely makes rows harder to scan. Before deleting them, make sure spacing, backgrounds, or section grouping still make the list readable.

This is especially important in settings screens and long text-heavy lists, where separators often act as lightweight visual structure rather than decoration.

Common Pitfalls

  • Setting separatorStyle = .none but forgetting about empty-row separators.
  • Removing separators when adjusted insets would have solved the design issue.
  • Hiding built-in separators and then forgetting to add visual separation another way.
  • Custom-drawing separators in cells without considering reuse and layout.
  • Assuming every visible line belongs to the actual populated rows.

Summary

  • Use tableView.separatorStyle = .none to remove built-in separators.
  • Add an empty tableFooterView to remove separators for unused rows.
  • Adjust separatorInset if you want a different look instead of no separators.
  • Hide the system separators and draw your own if you need full styling control.
  • Always keep row readability in mind when removing visual dividers.

Course illustration
Course illustration

All Rights Reserved.