How to remove the last border of the last cell in UITableView?
IphoneObjective CIosXcodeUitableviewIphone Problem Overview
In my app, I use a UITableView
My problem is that I want to remove the last border of the last cell in UITableView
.
Please check the following image:
Iphone Solutions
Solution 1 - Iphone
The best solution is add a footer view. The following code hide the last cell's line perfectly:
Objective-C
self.tableView.tableFooterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.tableView.frame.size.width, 1)];
Swift 4.0
tableView.tableFooterView = UIView(frame: CGRect(x: 0, y: 0, width: tableView.frame.size.width, height: 1))
Solution 2 - Iphone
In iOS 7 there is an easier solution. Supposing cell is your last cell:
cell.separatorInset = UIEdgeInsetsMake(0, cell.bounds.size.width, 0, 0);
Solution 3 - Iphone
Updated on 9/14/15. My original answer become obsolete, but it is still a universal solution for all iOS versions:
You can hide tableView
's standard separator line, and add your custom line at the top of each cell. The easiest way to add custom separator is to add simple UIView
of 1px height:
UIView* separatorLineView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, cell.bounds.size.width, 1)];
separatorLineView.backgroundColor = [UIColor grayColor];
[cell.contentView addSubview:separatorLineView];
To date, I subscribe to another way for hiding extra separators below cells (works for iOS 6.1+):
self.tableView.tableFooterView = [[UIView alloc] initWithFrame:CGRectZero];
Solution 4 - Iphone
This works for me in iOS 7 and 8:
cell.separatorInset = UIEdgeInsetsMake(0, 0, 0, CGRectGetWidth(tableView.bounds));
NOTE: be careful about using tableView.bounds
as it sometimes reports the wrong value depending on when you call it. See https://stackoverflow.com/questions/5194504/reporting-incorrect-bounds-in-landscape-mode
Solution 5 - Iphone
Add this line of code in viewDidLoad()
.
tableView.tableFooterView = UIView(frame: CGRect(x: 0, y: 0, width: 0, height: 0.001))
This make sure the last separator will be replaced and replaced (invisible) footer view will not occupy any extra height. Since the footer view's width will be managed by UITableView
, so you can set it to 0.
Solution 6 - Iphone
Extension based solution for Swift 4, tested on iOS 12
I noticed that setting a empty view of height = 1
also removes the separator of the last visible cell however setting height = 0
just removes the separator of the empty cells
extension UITableView {
func removeSeparatorsOfEmptyCells() {
tableFooterView = UIView(frame: .zero)
}
func removeSeparatorsOfEmptyCellsAndLastCell() {
tableFooterView = UIView(frame: CGRect(origin: .zero, size: CGSize(width: 0, height: 1)))
}
}
Solution 7 - Iphone
My shorter version:
self.tblView.tableFooterView = [UIView new];
Solution 8 - Iphone
In Swift simply:
tableView.tableFooterView = UIView()
Solution 9 - Iphone
Here is the remedy I currently use. it might not be the best approach, but it works.
Remove SeparatorColor and setSeparatorStyle to make custom separator
- (void)viewDidLoad
{
[super viewDidLoad];
...
[self.tableView setSeparatorStyle:UITableViewCellSeparatorStyleNone];
[self.tableView setSeparatorColor:[UIColor clearColor]];
}
Add custom separator to each cell with tableview background
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath];
...
UIView* separatorLineView = [[UIView alloc] initWithFrame:CGRectMake(0, cell.frame.size.height-1, 320, 1)];
separatorLineView.backgroundColor = self.tableView.backgroundColor;
[cell.contentView addSubview:separatorLineView];
return cell;
}
Solution 10 - Iphone
_tableView.tableFooterView = [[UIView alloc] initWithFrame:CGRectZero];
Solution 11 - Iphone
For iOS 7 and above
-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
BOOL bIsLastRow = NO;
//Add logic to check last row for your data source
NSDictionary *dict = [_arrDataSource objectAtIndex:indexPath.section];
if([_arrDataSource lastObject] == dict)
{
bIsLastRow = YES;
}
//Set last row separate inset left value large, so it will go outside of view
if ([cell respondsToSelector:@selector(setSeparatorInset:)])
{
[cell setSeparatorInset:UIEdgeInsetsMake(0, bIsLastRow ? 1000 :0, 0, 0)];
}
}
Solution 12 - Iphone
Below code helps me to remove the separator from last row in a UITableView.
Swift 3.0
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
if indexPath.row == tableView.numberOfRows(inSection: indexPath.section) {
cell.separatorInset.right = cell.bounds.size.width
}
}
Solution 13 - Iphone
Swift 4.2
To get a separator that goes from left to right in your last cell, add this in your UITableViewDataSource's
tableView(_:cellForRowAt:)
implementation:
if tableView.numberOfRows(inSection: indexPath.section) - 1 == indexPath.row {
cell.separatorInset = .zero
}
If you don't want a separator for one particular cell, consider drawing your own separator and set tableView.separatorStyle = .none
.
Solution 14 - Iphone
Xcode 12, Swift 5
for removing separator after last cell, select grouped UITableView style You can do that in Interface Builder or setup it in viewDidLoad
tableView.style = UITableView.Style.grouped
remove empty space before first cell, write this code in viewDidLoad:
tableView.tableHeaderView = UIView(frame: CGRect(x: 0, y: 0, width: tableView.bounds.width, height: 0.1))
for removing empty space before your cells, and you are going to scroll it under the navigation bar or have other difficulties with avoiding empty space, try to constraint your table to controller's super view Here double click the top constraint and then choose 'SuperView.Top' at the constraint settings
If you want full width separator or your own width of it, just select Separator Inset as Custom, and configure to your values, or write it in viewDidLoad:
tableView.separatorInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
Solution 15 - Iphone
Find the last cell index in the cellForRow
delegate and put the line of code from below:
cell.separatorInset = UIEdgeInsetsMake(
0.f,
40.0f,
0.f,
self.view.frame.size.width-40.0f
);
Solution 16 - Iphone
Another option is by subclassing UITableView
:
@synthesize hideLastSeparator = _hideLastSeparator;
@synthesize hideLastSeparatorView = _hideLastSeparatorView;
-(void)setHideLastSeparator:(BOOL)hideLastSeparator {
if (_hideLastSeparator == hideLastSeparator) {
return;
}
_hideLastSeparator = hideLastSeparator;
if (_hideLastSeparator) {
_hideLastSeparatorView = [[UIView alloc] initWithFrame:CGRectMake(0, self.contentSize.height, self.bounds.size.width, 0.5f)];
_hideLastSeparatorView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleBottomMargin;
_hideLastSeparatorView.backgroundColor = self.backgroundColor;
[self addSubview:_hideLastSeparatorView];
[self hideSeparator];
}
else {
[_hideLastSeparatorView removeFromSuperview];
_hideLastSeparatorView = nil;
}
}
-(void)setContentSize:(CGSize)contentSize {
[super setContentSize:contentSize];
if (_hideLastSeparator) {
[self hideSeparator];
}
}
-(void)hideSeparator {
CGRect frame = _hideLastSeparatorView.frame;
frame.origin.y = self.contentSize.height - frame.size.height;
_hideLastSeparatorView.frame = frame;
}
The .h should only contain property declarations for hideLastSeparator
and hideLastSeparatorView
.
When wanting to hide the separator, use the new class and set myTableView.hideLastSeparator = YES
.
The way this works is by obstructing the last separator by adding a new view over it.
This is somewhat easier to use in my opinion (than using a custom separator, or setting the last separatorInset of the last cell), and avoids some weird animations that the method of setting a tableFooterView
sometimes causes (e.g. during row insertion/deletion or other table animations).
Solution 17 - Iphone
If you're using custom separators for your UITableViewCell
the best solution is:
- Implement in your custom cell function, that hides
separatorView
class YourCell: UITableViewCell {
// Your implementation goes here...
// Separator view in cell
@IBOutlet private weak var separatorView: UIView!
// This function hides the separator view
func hideSeparator() {
separatorView.isHidden = true
}
}
- In
tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath)
calculate if the cell is the last and hides it's separator
public func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
guard let cell = cell as? YourCell else {
return
}
// Here we're checking if your cell is the last one
if indexPath.row == tableView.numberOfRows(inSection: indexPath.section) - 1 {
// if true -> then hide it
cell.hideSeparator()
}
}
Solution 18 - Iphone
This works great for me:
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
guard let cell = cell as? yourCell else {
return
}
// Here we're checking if your cell is the last one
if indexPath.row == numberOfCells.count - 1 {
cell.separatorInset.left = UIScreen.main.bounds.width
}
}
What we're doing here is setting the size of the left inset to be a big enough value so that the separator line won't be visible anymore. So when we increase the size value of our inset it will get closer and closer to the right of our screen since left inset goes towards the right direction.
Solution 19 - Iphone
The most suitable & easy way would be using this at cellForRowAt
cell.drawBottonLine = (indexPath.row != sections[0].rows.count - 1)
Solution 20 - Iphone
Expanding on Tonny Xu's answer, I have multiple sections and this seems to work for removing the last cells separator
if(indexPath.row == [self.tableView numberOfRowsInSection:indexPath.section] - 1)
{
self.tableView.tableFooterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.tableView.frame.size.width, 1)];
}
In the cellForRowAtIndexPath
datasource