iOS 9 UITableView separators insets (significant left margin)

36,323

Solution 1

Okay, I have found out the solution. The only thing required for that is to set on the presenting instance of UITableView that flag cellLayoutMarginsFollowReadableWidth

myTableView.cellLayoutMarginsFollowReadableWidth = NO;

I wanted to find some reference in the documentation but it looks like it is not ready yet, only mentioned on diff page.

As the flag was introduced in iOS 9 for the backward compatibility you should add a check before trying to set it:

if([myTableView respondsToSelector:@selector(setCellLayoutMarginsFollowReadableWidth:)])
{
    myTableView.cellLayoutMarginsFollowReadableWidth = NO;
}

For Swift 2.0 you can use #available to check iOS version.

if #available(iOS 9, *) {
    myTableView.cellLayoutMarginsFollowReadableWidth = false
}

Moreover you need to compile it with Xcode 7 or above.

EDIT

Please keep in mind that this is the only required fix if your separators looked "fine" up to iOS 8, otherwise you need to change a bit more. You can find info how to do this already on SO.

Solution 2

If you want to do it in interface builder. The default separator inset is Automatic. Change it to custom by selecting the dropdown.

enter image description here

Solution 3

Swift 2.2 iOS 9.3

In viewDidLoad

tableView.cellLayoutMarginsFollowReadableWidth = false

In UITableViewDelegates

func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
    if cell.respondsToSelector(Selector("setSeparatorInset:")){
        cell.separatorInset = UIEdgeInsetsZero
    }
    if cell.respondsToSelector(Selector("setPreservesSuperviewLayoutMargins:")) {
        cell.preservesSuperviewLayoutMargins = false
    }
    if cell.respondsToSelector(Selector("setLayoutMargins:")){
        cell.layoutMargins = UIEdgeInsetsZero
    }
}

Solution 4

Perfect Solution upto iOS 9

In viewDidLoad

- (void)viewDidLoad {
    [super viewDidLoad];
    //Required for iOS 9
    if ([[[UIDevice currentDevice]systemVersion]floatValue] >= 9.0) {
        self.testTableView.cellLayoutMarginsFollowReadableWidth = NO;
    }
}

In TableViewDelegate methods add following code:

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

    // Remove seperator inset
    if ([cell respondsToSelector:@selector(setSeparatorInset:)]) {
        [cell setSeparatorInset:UIEdgeInsetsZero];
    }

    // Prevent the cell from inheriting the Table View's margin settings
    if ([cell respondsToSelector:@selector(setPreservesSuperviewLayoutMargins:)]) {
        [cell setPreservesSuperviewLayoutMargins:NO];
    }

    // Explictly set your cell's layout margins
    if ([cell respondsToSelector:@selector(setLayoutMargins:)]) {
        [cell setLayoutMargins:UIEdgeInsetsZero];
    }
}

Solution 5

Swift 3.0 / 4.0

tableView.cellLayoutMarginsFollowReadableWidth = false

func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
    if cell.responds(to: #selector(setter: UITableViewCell.separatorInset)) {
        cell.separatorInset = UIEdgeInsets.zero
    }
    if cell.responds(to: #selector(setter: UIView.preservesSuperviewLayoutMargins)) {
        cell.preservesSuperviewLayoutMargins = false
    }
    if cell.responds(to: #selector(setter: UIView.layoutMargins)) {
        cell.layoutMargins = UIEdgeInsets.zero
    }
}
Share:
36,323
Julian
Author by

Julian

iOS developer with 9+ years of experience. If you want to know more about me you can take a look at: CodeMobile talk slideshare account Cherries of the AppCode Julian Król's take on AppCode All my answers are solely my private opinion and can not be referenced to my current, as well as previous, employer(s).

Updated on July 09, 2022

Comments

  • Julian
    Julian almost 2 years

    I have a problem with separators between UITableViewCells in UITableView on iOS 9. They have the significant left margin. I already have code for removing spacing introduced by iOS 8 but it doesn't work with iOS 9. It looks like they added something else. I suppose it might be connected with layoutMarginsGuide but I haven't figured it out yet. Does anyone had a similar problem and found out the solution?

  • Julian
    Julian almost 9 years
    Not in my case. This was working fine up to the version 8 of iOS. Something else seems to be required for iOS 9.
  • JonEasy
    JonEasy over 8 years
    Thanks for that! is there any option to turn this feature off for the whole app or do I have to manually Update all TableViewController properties?
  • Julian
    Julian over 8 years
    Have you considered creating a base class for tableview (set it there) and use it wherever possible? Moreover I would look if it can be set by appearance.
  • JonEasy
    JonEasy over 8 years
    yes this is what I'm doing right now (base class approach) I was just wondering if there would be some kind of "global switch" to shut this off completely. I tried the appearance stuff but this doesn't work with [[UITableView appearance] setCellLayoutMarginsFollowReadableWidth:NO];
  • Julian
    Julian over 8 years
    Maybe that could be a next SO question how (if possible) to set it globally :)
  • Julian
    Julian over 8 years
    First of all, if you copy code from the other answer on SO it would be nice if you mention the original author with a link to its answer (that would be fair). Secondly instead of checking iOS version you can check whether object responds to selector.
  • Bhuvan Bhatt
    Bhuvan Bhatt over 8 years
    @JulianKról You are right about respond to selector its an alternative. And this is my solution I have created a demo project for this too and working properly on all iOS versions. It would really feel great if you appreciate.
  • Julian
    Julian over 8 years
    yeah but the second part of the code I already seen on the SO with same comments etc. Moreover making every thing bold and italic also do not improves its readability :) Further, the question is explicit about iOS 9 assuming that up to iOS 8 everything was already done (that counts to the second part of your answer). I appreciate yours involvement but I'm giving you my feedback
  • Bhuvan Bhatt
    Bhuvan Bhatt over 8 years
    Yeah that was actually I was using till iOS 8. But for iOS 9 besides this code one must set self.testTableView.cellLayoutMarginsFollowReadableWidth = NO . So for the proper answer I have mentioned the complete code.
  • Julian
    Julian over 8 years
    what about link to the original answer on SO ? you didn't say anything about that :)
  • Bhuvan Bhatt
    Bhuvan Bhatt over 8 years
    @JulianKról Ok noted. Will keep this in mind for future. Thnks.
  • Qian Chen
    Qian Chen over 8 years
    Doesn't seem to have any effect on iOS 9.1.
  • Julian
    Julian over 8 years
    @ElgsQianChen has it worked for you for previous versions?
  • Qian Chen
    Qian Chen over 8 years
    @JulianKról I haven't tried with any earlier version yet.
  • Julian
    Julian over 8 years
    So this is only the addition you need if your separators where fine on iOS 8. This is what changed between iOS 8 and 9. Find how to fix it on iOS 8 (it is already on SO) and add this and you are done.
  • codelearner
    codelearner about 8 years
    As a workaround, I have just put constraint of -14 for UITableView instead of using above codes to align the table manually.
  • manroe
    manroe over 7 years
    this is what I needed! The order matters. For me, I noticed that the order mattered for iPad table views in landscape. Once rotated it was fixed, but the first sight of the table was wrong. Thank you!
  • RanLearns
    RanLearns almost 7 years
    Thanks for this! Any idea why, on iPad, this code makes a full width separator on empty cells, but when data is added to a cell there are a few pixels on the left side where the separator is missing? I found a patch/fix for this but just wondering if you may know more.
  • Steffo Dimfelt
    Steffo Dimfelt over 5 years
    The "Seperator Inset" is Automatic as default and do not show Left/Right unti it is changed to Custom.