ChatGPT解决这个技术问题 Extra ChatGPT

How to set the full width of separator in UITableView

I have a UITableView where the separators don't have the full width. It ends like 10 pixels before the left side. I was playing around with this code in the viewDidLoad().

self.tableView.layoutMargins = UIEdgeInsetsZero;

Also in the storyboard when you can select custom or default selectors. Now all the cells that are populated don't have the full-width selectors but the cells that are empty have full width.

How can I fix this?

UITableView has a property separatorInset. Set the inset of the UITableViewline separator to zero. Also you can change the separatorInset from the storyboard

S
SwiftiSwift

This worked for me on iOS 8.4 - 9.0 devices using Xcode 6.4 and Swift 1.2:

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    var cell = UITableViewCell()


    cell.preservesSuperviewLayoutMargins = false
    cell.separatorInset = UIEdgeInsetsZero
    cell.layoutMargins = UIEdgeInsetsZero

    return cell
}

Swift 5 Update:

cell.preservesSuperviewLayoutMargins = false
cell.separatorInset = UIEdgeInsets.zero
cell.layoutMargins = UIEdgeInsets.zero

Why does this remove my table with a blank one? The seperators are moved but I cant see any of my buttons
@James could you please explain " remove my table with a blank one?". How have you added your buttons (via IB, code)?
Very nice solution. But in my case I put code straight to the cell initialization, beacuse I wanted to have full width of separator in all controllers.
In case it isn't obvious, this also works for Objective-C with the proper syntax changes of course.
None of these solutions work on an iPad. This only works on an iPhone...
K
Kuldeep

In your UITableViewCell

Go to Attributes Inspector in your Interface Builder and simply change "15" to 0. Do this for all the cells you wish to change.

https://i.stack.imgur.com/A8rY1.png

You may need to add [cell setLayoutMargins:UIEdgeInsetsZero]; to your tableViewCell


Or that's weird. This did work for me (thank you !) on the rows where I had UITableViewCells to be displayed, but on any empty rows below them, the separator was still indented by 15 pixels.
If you are using static cells, all you need is to change the left inset to 0 like described in the image (Working in iOS 10, Xcode 8.3.1)
N
Nilanshu Jaiswal

I got the answer from this post: iOS 8 UITableView separator inset 0 not working

Just add this code on your UITableViewController

-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
    if ([cell respondsToSelector:@selector(setSeparatorInset:)]) {
        [cell setSeparatorInset:UIEdgeInsetsZero];
    }

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

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

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

it works for me for adding only the tableView delegate method
Im sorry i did not understad. You mean that it was enough for you to add the TableViewDeleagte?. I just tried just adding that it did not work for me @TonyTony
for me the method viewDidLayoutSubviews is not necessary
DId you try to run your code with other IOS versions than 8? Maybe it works for the newest ones. Otherwise good for you that it works. I tried just adding the tableview delegate method and it did not help. @TonyTony
I had to use both. I tried using each individually with no success. It only worked when I used both. In addition, I tried it when my view controller was a subclass of UITableViewController, and when it was a subclass of UIViewController. No difference. Note that I'm running in the 8.1 simulator.
W
Wilson

for Swift 3 :

override func viewDidLoad() {
  super.viewDidLoad()

  tableView.separatorInset = .zero
  tableView.layoutMargins = .zero
}

N
Nilanshu Jaiswal

Select your UITableViewCell Go to Atributes Inspector Go to Separator and change it to "custom Insets" Set left and / or right fields. (By default left: 15, right: 0)

Look how it works (using left: 100):

https://i.stack.imgur.com/zlC8T.png

Result:

https://i.stack.imgur.com/Uuv0N.png


duplicate of previous answer from @Hannah Louisa Carney
N
Nilanshu Jaiswal

I inherit from UITableViewController and needed additional to the two insets settings in willDisplayCell also to set preservesSuperviewLayoutMargins to false. In Swift it looks like this:

override func tableView(_tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {

    if cell.respondsToSelector("setSeparatorInset:") {
        cell.separatorInset = UIEdgeInsetsZero
    }
    if cell.respondsToSelector("setLayoutMargins:") {
        cell.layoutMargins = UIEdgeInsetsZero
    }
    if cell.respondsToSelector("setPreservesSuperviewLayoutMargins:") {
        cell.preservesSuperviewLayoutMargins = false
    }
}

You don't need to set preservesSuperviewLayoutMargins = false because default value is already false
Note that this won't adjust the separators on 'placeholder' cells displayed by the controller to fill up the view below your cells if you cells don't make up the full height.
A
Ali

The Separator Inset is by default 15 from left. Change Separator Inset option from auto to custom and set the inset to 0.

https://i.stack.imgur.com/l40TC.png


N
Nilanshu Jaiswal

For Swift in iOS 9+

If using a custom UITableViewCell:

override var layoutMargins: UIEdgeInsets {
    get { return UIEdgeInsetsZero }
    set(newVal) {}
}

then for your UITableView in viewDidLoad:

self.tableView?.separatorInset = UIEdgeInsetsZero;
self.tableView?.layoutMargins = UIEdgeInsetsZero;

This is the only answer that fixed it for me (updated to swift 3). However... it works when there is data in the cell. For blank cells that have not yet been filled (and I guess haven't called this overriden layoutMargins variable) the separator still does not fill the full width of my custom cell in the tableview. Any ideas on that?
On the iPhone, the separator ends just a few pixels from the left and a few pixels from the right on empty cells. That looks alright without using this trick to zero out the margins. On the iPad is the real problem - the separators on an empty cell go from the left edge of the tableview, only about 80% of the width of the cell. When there is data in the cell, the separator is still 80% of the cell width, but it starts 20% of the way in and goes all the way to the right edge of the tableview
Figured out a solution... using if #available(iOS 9, *) { self.tableView.cellLayoutMarginsFollowReadableWidth = false } made it so I don't need your code at all on iPhone. The separator just goes the full width. On iPad, the empty cells have a full width separator, but I need your code in order to keep full width when data is added. Otherwise, there are a few pixels to the left added where there is no separator once data fills the cell.
Answer where I got the code in the comment above from: stackoverflow.com/a/31538250/428981
N
Nilanshu Jaiswal

For people having issues with the iPad — this will get you in a state that is the same as the iPhone. You can then adjust the separatorInset as needed.

tableView.cellLayoutMarginsFollowReadableWidth = false

This was my problem on iOS 10 vs iOS 11. iOS 11 was fine, but 10 had different margins. Thanks!!!
A
Ash

Use it in cellForRowAtIndexPath method, to configure cell's separator specs ,
it works perfect for iOS9.0+

 cell.separatorInset = UIEdgeInsetsZero;
 cell.layoutMargins = UIEdgeInsetsZero;
 cell.preservesSuperviewLayoutMargins = NO;

N
Nilanshu Jaiswal

Tested for iOS 9.3 & Swift 2.2. Make sure to put the code in willDisplayCell which is called just before displaying the cell and not in cellForRowAtIndexPath where you create the cell only.

func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
    cell.separatorInset = UIEdgeInsetsZero
    cell.layoutMargins = UIEdgeInsetsZero
}

Add override to the function for UITableViewController, like so:

override func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {

D
Developersian

swift 5, Xcode 11 Update

place this inside viewDidLoad()

yourTableView.separatorInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)

for edge to edge separator just set the value of left and right to 0.

by the way change the "yourTableView" to your tableView Outlet name.


Swift 5 you can simple use UIEdgeInsets.zero
K
Kuldeep

None of the above worked for me in Swift 2.2 and Xcode 7.3.1

Turned out to be the simplest solution of all. No code needed. Just change TableViewCell Layout Margins values in your UITableView inspector:

https://i.stack.imgur.com/0TC8z.png


N
Nilanshu Jaiswal

For Swift 3 :

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: UITableViewCell.layoutMargins)) {
        cell.layoutMargins = UIEdgeInsets.zero
    }
    if cell.responds(to: #selector(setter: UITableViewCell.preservesSuperviewLayoutMargins)) {
        cell.preservesSuperviewLayoutMargins = false
    }
}

G
Giang

In viewDidLoad (tested iOS11 - swift 4.1)

try

tableView.separatorInset = UIEdgeInsetsMake(0, 0, 0, 0)


K
Kuldeep

None of these solutions work on the iPad, but I have come up with a solution that covers both devices:

With reusable cells:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
    ...[other code]...
    [cell setLayoutMargins:UIEdgeInsetsZero];
    [cell setSeparatorInset:UIEdgeInsetsZero];
    return cell;
}

With non reusable cells:

- (void)removeSeparatorInset:(UITableView*)tableView{
    NSArray *cells = [tableView visibleCells];
    for (UITableViewCell *cell in cells){
        [cell setLayoutMargins:UIEdgeInsetsZero];
        [cell setSeparatorInset:UIEdgeInsetsZero];
    }
}

-(void) viewDidLayoutSubviews{
   [super viewDidLayoutSubviews];
   [self removeSeparatorInset:self.tableView];
}

Just to expand on this approach:

@property(nonatomic) UIEdgeInsets separatorInset;
@property(nonatomic) UIEdgeInsets layoutMargins;

Both properties can be used by UITableView & UITableViewCell. The latter is, in fact, a property of UIView, which is a parent class of both UITableView & UITableViewCell.


The only workable solution I found for non reusable cells