Is there a way to make UITableView cells in iOS 7 not have a line break in the separator?

UitableviewIos7

Uitableview Problem Overview


I noticed that in iOS 7, UITableViewCells have a line break in the separator of the cell that iOS 6 does not have. Is there a way to get rid of this line break? Changing the separator to none and then making UIViews with the color of the separator still causes the white separator to occur regardless.

Uitableview Solutions


Solution 1 - Uitableview

For iOS7:

if ([self.tableView respondsToSelector:@selector(setSeparatorInset:)]) {
    [self.tableView setSeparatorInset:UIEdgeInsetsZero];
}

For iOS8:

First configure your table view as follows:

if ([self.tableView respondsToSelector:@selector(layoutMargins)]) {
    self.tableView.layoutMargins = UIEdgeInsetsZero;
}

Then in your cellForRowAtIndexPath: method, configure the cell as follows:

if ([cell respondsToSelector:@selector(layoutMargins)]) {
    cell.layoutMargins = UIEdgeInsetsZero;
}

Note: Include both layoutMargins and separatorInset, to support both iOS versions

Solution 2 - Uitableview

You can also set the 'Separator Inset' from the storyboard:

enter image description here

enter image description here

Solution 3 - Uitableview

If you want to support older versions of iOS, you should check for the availability of this method before calling it:

if ([self.tableView respondsToSelector:@selector(setSeparatorInset:)]) {
    [self.tableView setSeparatorInset:UIEdgeInsetsZero];
}

Solution 4 - Uitableview

Figured it out.

[self.tableView setSeparatorInset:UIEdgeInsetsMake(0, 0, 0, 0)];

Solution 5 - Uitableview

The selected answer did not work for me. But this yes and it works from ios 2.0:

   [self.tableView setSeparatorStyle:UITableViewCellSeparatorStyleNone];

Solution 6 - Uitableview

Swift version

iOS introduces the layoutMargins property on cells AND table views.

This property isn't available in iOS 7.0 so you need to make sure you check before assigning it!

However, Apple has added a **property to your cell that will prevent it from inheriting your Table View's margin settings. This way, your cells can configure their own margins independently of the table view. Think of it as an override.

This property is called preservesSuperviewLayoutMargins, and setting it to NO can allow you to override your Table View's layoutMargin settings with your own cell's layoutMargin setting. It both saves time (you don't have to modify the Table View's settings), and is more concise. Please refer to Mike Abdullah's answer for a detailed explanation.

NOTE: this is the proper, less messy implementation, as expressed in Mike Abdullah's answer; setting your cell's preservesSuperviewLayoutMargins=NO will ensure that your Table View does not override the cell settings.

First step - Setup your cell margins:

/*
    Tells the delegate the table view is about to draw a cell for a particular row.
*/
override func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell,
    forRowAtIndexPath indexPath: NSIndexPath)
{
    // Remove seperator inset
    if cell.respondsToSelector("setSeparatorInset:") {
        cell.separatorInset = UIEdgeInsetsZero
    }
    
    // Prevent the cell from inheriting the Table View's margin settings
    if cell.respondsToSelector("setPreservesSuperviewLayoutMargins:") {
        cell.preservesSuperviewLayoutMargins = false
    }
    
    // Explictly set your cell's layout margins
    if cell.respondsToSelector("setLayoutMargins:") {
        cell.layoutMargins = UIEdgeInsetsZero
    }
}

Setting the preservesSuperviewLayoutMargins property on your cell to NO should prevent your table view from overriding your cell margins. In some cases, it seems to not function properly.

Second step - Only if all fails, you may brute-force your Table View margins:

/*
    Called to notify the view controller that its view has just laid out its subviews.
*/
override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    
    // Force your tableview margins (this may be a bad idea)
    if self.tableView.respondsToSelector("setSeparatorInset:") {
        self.tableView.separatorInset = UIEdgeInsetsZero
    }
    
    if self.tableView.respondsToSelector("setLayoutMargins:") {
        self.tableView.layoutMargins = UIEdgeInsetsZero
    }
}

...and there you go! This should work on iOS 8 as well as iOS 7.

Note: tested using iOS 8.1 and 7.1, in my case I only needed to use The First Step of this explanation.

The Second Step is only required if you have unpopulated cell beneath the rendered cells, ie. if the table is larger than the number of rows in the table model. Not doing the second step would result in different separator offsets.

Solution 7 - Uitableview

For a permanent solution app-wide, call this in application:didFinishLaunching .. any tableview will be "fixed"

if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7) {
  [[UITableView appearance]setSeparatorInset:UIEdgeInsetsZero];
}

Solution 8 - Uitableview

And in iOS 8, based on the Seth McFarlane post here, you need to start dealing with layoutMargins. The following did it for me:

  1. In ApplicationDidFinishLaunching, run the following:

    if ([UITableViewCell instancesRespondToSelector:@selector(setLayoutMargins:)]) {
    	[[UITableViewCell appearance]setLayoutMargins:UIEdgeInsetsZero];
    }
    
  2. Create the following category on UITableView:

    @interface UITableView(WJAdditions)
    -(void) wjZeroSeparatorInset;
    @end
    
    @implementation UITableView (WJAdditions)
    -(void) wjZeroSeparatorInset {
    #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000
      if ([self respondsToSelector:@selector(setLayoutMargins:)]) {
    	self.layoutMargins = UIEdgeInsetsZero;
      }
    #endif
    #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000
       if ([self respondsToSelector: @selector(setSeparatorInset:)])
          self.separatorInset = UIEdgeInsetsZero;
       }
    #endif
    }
    @end
    
  3. In your UITableViews, shortly after initializing, call

    [self wjZeroSeparatorInset];
    
  4. In your UITableViewControllers, you need the following:

    -(void) viewWillLayoutSubviews {
      [super viewWillLayoutSubviews];
      UITableView* tv = self.tableView;
      if ([tv respondsToSelector:@selector(setLayoutMargins:)]) {
        [tv setLayoutMargins:UIEdgeInsetsZero];
      }
    }
    

Solution 9 - Uitableview

In iOS 8, there appears to be a small bug. The custom value for separator inset doesn't get applied to the cells with text in it. I tried setting it from the interface builder and through code but neither worked. I've filed a bug report as well.

enter image description here

In the meantime, I have a small workaround to achieve this. I simply draw the line on the cell. Create a subclass of UITableViewCell and override the drawRect method. Also don't forget to set the separator property of the UITableView to None. Here is the code. It's in Swift but since its basically C, you can use the same thing in Objective-C as well.

override func drawRect(rect: CGRect) {
    super.drawRect(rect)
    
    let context = UIGraphicsGetCurrentContext()
    CGContextSetStrokeColorWithColor(context, UITableView().separatorColor.CGColor) // seperator color
    CGContextSetLineWidth(context, 2) // separator width
    
    CGContextMoveToPoint(context, 0, self.bounds.size.height)
    CGContextAddLineToPoint(context, self.bounds.size.width, self.bounds.size.height)
    CGContextStrokePath(context)
}

Solution 10 - Uitableview

Reset separatorInset fixes this problem for me:

if ([self.tableView respondsToSelector:@selector(setSeparatorInset:)]) {
    [self.tableView setSeparatorInset:self.tableView.separatorInset];
}

Solution 11 - Uitableview

The solution:

-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath{

    if ([tableView respondsToSelector:@selector(setSeparatorInset:)]) {
        [tableView setSeparatorInset:UIEdgeInsetsZero];
    }

    if ([tableView respondsToSelector:@selector(setLayoutMargins:)]) {
        [tableView setLayoutMargins:UIEdgeInsetsZero];
    }

   if ([cell respondsToSelector:@selector(setLayoutMargins:)]) {
        [cell setLayoutMargins:UIEdgeInsetsZero];
   }
}

Solution 12 - Uitableview

Beware as setting the separatorInset of tableView to UIEdgeInsetsZero seems to break the left margin of section titles at the same time! (at least it does on iOS 7.1)

If you want to display section titles with tableView:titleForHeaderInSection: and still get the desire effect of no line break between UITableViewCells, you must set the separatorInset directly on the cells instead of the tableView!

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    // ...
    [cell setSeparatorInset:UIEdgeInsetsZero];

Solution 13 - Uitableview

For iOS8+ this worked for me,

tableView.layoutMargins = UIEdgeInsetsZero

and in cellForRowAtIndexPath method:

cell.layoutMargins = UIEdgeInsetsZero;

Solution 14 - Uitableview

- (void)viewDidLoad
{
    [self.tableView setSeparatorStyle:UITableViewCellSeparatorStyleNone];
    
    [super viewDidLoad];

    // Additional setup
}

Note: the setSeparatorStyle line has to be above the super call.

Solution 15 - Uitableview

@implementation UITableView (HGApperance) 
-(void)setSeparatorXMargin:(CGFloat)margin{
    // iOS 7
    if ([self respondsToSelector:@selector(setSeparatorInset:)]) {
        [self setSeparatorInset:UIEdgeInsetsZero];
    }

    if ([self respondsToSelector:@selector(layoutMargins)]) {
        self.layoutMargins = UIEdgeInsetsZero;
    }
}
@end

For TableviewCell, Willam's answer works perfect.

Solution 16 - Uitableview

To iOS8 and above

If you find that all the solutions don't work like me, I think you may have used the subclass of UITableViewCell and override the layoutSubviews method, if you meet two the conditions, go on reading.

Do or check it step by step.

1、After alloc and init the UITableView, set its layoutMargins property.

if ([_tableView respondsToSelector:@selector(setLayoutMargins:)]) {
    _tableView.layoutMargins = UIEdgeInsetsZero ;
}

2、In the method - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath, after alloc and init your custom UITableViewCell, set its layoutMargins property.

if ([cell respondsToSelector:@selector(setLayoutMargins:)]) {
    cell.layoutMargins = UIEdgeInsetsZero ;
}

3、The most important part comes in. If you override the - (void)layoutSubviews method of UITableViewCell, don't forget to call its super.

- (void)layoutSubviews
{
    [super layoutSubviews] ;
    
    // layout the subviews
}

Solution 17 - Uitableview

Xamarin.iOS Version

I extended the UITableView separator the full width in Xamarin.iOS on iOS 8.4 with help from posts by Luis E. Prado and King-Wizard. I had to set both SeparatorInset and LayoutMargins to get it working. I did not write checks for lower iOS versions since I am targeting iOS 8 and above.

I wrote the following two C# extension methods to set the UITableView separator full width at the UITableView or UITableViewCell level. You might use one or both of these methods depending on the desired effect (see the explanations below).

UITableView

Set the UITableView properties to alter the separators that appear after empty cells. This SetLayoutMarginsZero method could be called from the related ViewController's ViewDidLoad method.

public static void SetLayoutMarginsZero(this UITableView tableView)
{
	tableView.SeparatorInset = UIEdgeInsets.Zero;
	tableView.LayoutMargins = UIEdgeInsets.Zero;
}

UITableViewCell

Set the UITableViewCell properties to alter the separators that appear after populated cells. This SetLayoutMarginsZero method could be called from the TableViewSource GetCell method.

public static void SetLayoutMarginsZero(this UITableViewCell tableViewCell)
{
	tableViewCell.SeparatorInset = UIEdgeInsets.Zero;
	tableViewCell.LayoutMargins = UIEdgeInsets.Zero;
	tableViewCell.PreservesSuperviewLayoutMargins = false;
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAnthony GlyadchenkoView Question on Stackoverflow
Solution 1 - UitableviewLuis E. PradoView Answer on Stackoverflow
Solution 2 - UitableviewTarek HallakView Answer on Stackoverflow
Solution 3 - UitableviewboroView Answer on Stackoverflow
Solution 4 - UitableviewAnthony GlyadchenkoView Answer on Stackoverflow
Solution 5 - UitableviewanasaitaliView Answer on Stackoverflow
Solution 6 - UitableviewKing-WizardView Answer on Stackoverflow
Solution 7 - UitableviewRafael NobreView Answer on Stackoverflow
Solution 8 - UitableviewWilliam JockuschView Answer on Stackoverflow
Solution 9 - UitableviewIsuruView Answer on Stackoverflow
Solution 10 - Uitableviewuser2088250View Answer on Stackoverflow
Solution 11 - UitableviewTeaView Answer on Stackoverflow
Solution 12 - UitableviewBluezenView Answer on Stackoverflow
Solution 13 - UitableviewMohammad Zaid PathanView Answer on Stackoverflow
Solution 14 - UitableviewMatt RundleView Answer on Stackoverflow
Solution 15 - UitableviewHamGuyView Answer on Stackoverflow
Solution 16 - UitableviewKudoCCView Answer on Stackoverflow
Solution 17 - UitableviewMobile DanView Answer on Stackoverflow