UITableView: the proper way to display a separator for the last cell

31,483

Solution 1

This worked flawlessly for me to add a separator to the last cell. have fun!

self.tableView.tableFooterView = [[UIView alloc] init];

Solution 2

When you add headerView or footerView to your TableView, last separator line will disappear.

Example below will let you make workaround for showing separator on the last cell. The only thing you have to implement more is to make this separator disappearing after selecting cell, so behavior is the same like in the rest of cells.

For Swift 4.0

override func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {

    let result = UIView()

    // recreate insets from existing ones in the table view
    let insets = tableView.separatorInset
    let width = tableView.bounds.width - insets.left - insets.right
    let sepFrame = CGRect(x: insets.left, y: -0.5, width: width, height: 0.5)

    // create layer with separator, setting color
    let sep = CALayer()
    sep.frame = sepFrame
    sep.backgroundColor = tableView.separatorColor?.cgColor
    result.layer.addSublayer(sep)

    return result
}

Solution 3

I just found something that works for me. In a few words: give your UITableView a tableFooterView and set its frame's height to 0. This makes an actual separator show, with the right insets.

In more details: if you are using the storyboard, drag a UIView to the bottom of your Table View (in the tree view on the left) so it shows just below Table View Cell, at the same hierarchical level. This creates a tableFooterView. Of course this can be done programmatically as well.

Then, in your UITableViewController's implementation:

UIView *footerView = self.tableView.tableFooterView;
CGRect footerFrame = footerView.frame;
footerFrame.size.height = 0;
[footerView setFrame:footerFrame];

Let me know if that works for you! It might also work for the first separator if you use a tableHeaderView instead, I haven't tried it though.

Solution 4

So here's a super simple solution in Swift 4 which works:

Inside override func viewDidLoad(){}, I simply implemented this line of code:

    self.tableView.tableFooterView = UIView(frame: .zero)

Hence it ensures that only the last cell gets the separator inset.

This worked perfectly for me, hope it does for you too!

Solution 5

You can do something like this if you are not using sections:

- (void)viewDidLoad
{
     self.tableView.tableFooterView = [[UIView alloc] initWithFrame:CGRectMake(insetLeftSide, 0, width - insetRightSide, 1)];
}

If you are using sections implement the footer in each section as a one point View in the methods

- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section
{
}

- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section
{
}

This will allow you to have a separator for your last cell which in fact is not a separator is a footer that you can play with it and make it look like a separator

Share:
31,483
dariaa
Author by

dariaa

#SOreadytohelp

Updated on July 09, 2022

Comments

  • dariaa
    dariaa almost 2 years

    The question is what's the right-most way to display a separator in the last cell in a table/section.

    Basically this is what I am after.

    enter image description here This is from the native music app, which makes me think that it should be possible to achieve just by means of UITableView, they would not be using some private API for cell separators, right?

    I know you can get away without using actual separators, but adding one pixel line in the bottom of the cell. But I'm not a fan of this approach because

    1. When a cell is selected/highlighted its separator and the separator of the previous cell are automatically hidden (see the second screenshot with "You've got to be crazy" selected). And this is something I want UITableView to handle instead of doing myself if I use one-pixel line (which is especially handy when cell separators do not extend all the way to the edge of the table view, separators and selected cell background do not look nice together).
    2. I would like to keep my cells as flat as possible for scrolling performance.

    Also there is something in UITableView reference that makes me think that there is an easy way to get what I want:

    In iOS 7 and later, cell separators do not extend all the way to the edge of the table view. This property sets the default inset for all cells in the table, much like rowHeight sets the default height for cells. It is also used for managing the “extra” separators drawn at the bottom of plain style tables.

    Does somebody know how exactly to use these “extra” separators drawn at the bottom of plain style tables? Because this is exactly what I need. I thought assigning separatorInsetto the UITableView, not UITableViewCell would do the trick, but it does not, the last cell is still missing its separator.

    Right now I only see one option: to have a custom section footer to mimic the separator for the last cell. And this is not good, especially if you want to have an actual section footer using tableView:titleForFooterInSection: method.