I have a problem with separators between UITableViewCell
s 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?

- 9,299
- 5
- 48
- 65
-
Apple Developer Forum: https://forums.developer.apple.com/thread/20017 – matzino Oct 07 '15 at 17:04
-
This answer may help others with the same issues: http://stackoverflow.com/a/38206546/1137246 – Matjan Jul 05 '16 at 14:52
11 Answers
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.
-
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? – JonEasy Oct 19 '15 at 13:39
-
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. – Julian Oct 19 '15 at 13:46
-
1yes 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];` – JonEasy Oct 20 '15 at 07:41
-
Maybe that could be a next SO question how (if possible) to set it globally :) – Julian Oct 20 '15 at 07:42
-
2
-
-
-
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. – Julian Dec 14 '15 at 12:31
-
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. – RanLearns May 13 '17 at 02:30
If you want to do it in interface builder. The default separator inset is Automatic
. Change it to custom
by selecting the dropdown.

- 2,685
- 21
- 27
-
The "Seperator Inset" is Automatic as default and do not show Left/Right unti it is changed to Custom. – Steffo Dimfelt Aug 24 '18 at 11:29
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
}
}
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
}
}

- 14,784
- 16
- 90
- 139
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];
}
}

- 3,276
- 2
- 18
- 23
-
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. – Julian Dec 02 '15 at 16:23
-
@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. – Bhuvan Bhatt Dec 02 '15 at 16:28
-
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 – Julian Dec 02 '15 at 16:29
-
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. – Bhuvan Bhatt Dec 02 '15 at 16:31
-
1what about link to the original answer on SO ? you didn't say anything about that :) – Julian Dec 02 '15 at 16:38
-
This worked perfectly for me in iOS 9.
For OBJ-C
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(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];
}
return cell;
}

- 459
- 8
- 21
Based on different answers here, I am able to remove the gap from separator with these lines of codes in Swift:
tableView.separatorInset = UIEdgeInsetsZero
tableView.layoutMargins = UIEdgeInsetsZero
cell.separatorInset = UIEdgeInsetsZero
cell.layoutMargins = UIEdgeInsetsZero
But still I am having this small gap before the text:

- 1,354
- 1
- 16
- 32
-
As a workaround, I have just put constraint of `-14` for `UITableView` instead of using above codes to align the table manually. – codelearner Mar 29 '16 at 09:43
The accepted answer did not work for me. Until I moved setCellLayoutMarginsFollowReadableWidth
BEFORE setLayoutMargins
(still needed for iOS 8):
if([_tableView respondsToSelector:@selector(setCellLayoutMarginsFollowReadableWidth:)]) {
_tableView.cellLayoutMarginsFollowReadableWidth = NO;
}
if ([_tableView respondsToSelector:@selector(setLayoutMargins:)]) {
_tableView.layoutMargins = UIEdgeInsetsZero;
}
-
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! – manroe Nov 11 '16 at 19:49
- (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];
}
}

- 581
- 4
- 12
-
Not in my case. This was working fine up to the version 8 of iOS. Something else seems to be required for iOS 9. – Julian Jul 21 '15 at 11:13
For iOS 8 and 9
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
if ([UITableView instancesRespondToSelector:@selector(setLayoutMargins:)]) [[UITableViewCell appearance] setLayoutMargins:UIEdgeInsetsZero];
if ([UITableView instancesRespondToSelector:@selector(setPreservesSuperviewLayoutMargins:)]) [[UITableViewCell appearance] setPreservesSuperviewLayoutMargins:NO];
}
and
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
if ([cell respondsToSelector:@selector(setLayoutMargins:)]) [cell setLayoutMargins:UIEdgeInsetsZero];
}

- 21
- 3
This is my solution for Swift 3.0/iOS 10 in XCode 8.2.1.
I have created a subclass for UITableview which works for IB and programmatically create tableviews.
import UIKit
class EXCSuperTV: UITableView
{
required init?(coder aDecoder: NSCoder)
{
super.init(coder: aDecoder)
setupView()
}
override init(frame: CGRect, style: UITableViewStyle)
{
super.init(frame: frame, style: style)
setupView()
}
func setupView() {}
}
class EXCNoFooter: EXCSuperTV
{
override func setupView()
{
super.setupView()
//tableFooterView = UIView.Zero()
}
}
class EXCMainTV: EXCNoFooter
{
override func setupView()
{
super.setupView()
separatorInset = UIEdgeInsets.zero
}
}

- 1,149
- 1
- 13
- 26