iOS 9 UITableView separators insets (significant left margin)

安稳与你 提交于 2019-11-27 11:53:19
Julian Król

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.

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

H.Yuu

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
    }
}

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];
    }
}

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
    }
}

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:

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;
    }
Donnit

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;
}
- (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];
    }

}

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];
}

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
    }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!