如何在UITableView中设置分隔符的全宽


148

我有一个UITableView分隔符没有完整宽度的地方。它结束于左侧之前的10像素。我在中使用此代码viewDidLoad()

self.tableView.layoutMargins = UIEdgeInsetsZero;

同样在情节提要中,您可以选择自定义或默认选择器。现在,所有填充的单元格都没有全角选择器,但空单元格则具有全角选择器。

我怎样才能解决这个问题?


9
UITableView有财产separatorInset。将UITableView行分隔符的插入设置为零。您也可以改变separatorInset从故事板
KRUKUSA

Answers:


220

这在使用Xcode 6.4和Swift 1.2的iOS 8.4-9.0设备上为我工作:

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


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

    return cell
}

Swift 5更新:

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

为什么这会删除我的表中有一个空白的表?分隔符已移动,但我看不到任何按钮
奥斯卡

1
@James,请您解释一下“删除我的表并保留空白?”。您如何添加按钮(通过IB,代码)?
MB_iOSDeveloper

1
非常好的解决方案。但是在我的情况下,我将代码直接用于单元初始化,因为我想在所有控制器中都使用分隔符的完整宽度。
福伊塔

如果不太明显,这当然也适用于Objective-C,当然也要进行适当的语法更改。
cohenadair

1
这些解决方案均无法在iPad上运行。这仅适用于iPhone ...
Charles Robertson

103

我从这篇文章中得到了答案:iOS 8 UITableView分隔符插入0不起作用

只需将此代码添加到您的 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];
    }
}

2
它对我来说仅添加tableView委托方法有效
TonyTony 2015年

对不起,我没什么意思。您的意思是添加TableViewDeleagte吗?我只是尝试添加它对我不起作用@TonyTony
Timo Cengiz

3
对我来说,该方法viewDidLayoutSubviews不是必需的
TonyTony 2015年

您是否尝试使用非8的其他IOS版本运行代码?也许它适用于最新的。否则对您有利,它将起作用。我尝试仅添加tableview委托方法,但没有帮助。@TonyTony
Timo Cengiz

我必须同时使用两者。我尝试单独使用每个都没有成功。仅当我同时使用两者时才有效。另外,当视图控制器是UITableViewController的子类时,以及当它是UIViewController的子类时,我也尝试过。没有不同。请注意,我正在8.1模拟器中运行。
罗恩

99

在你的 UITableViewCell

转到Interface Builder中的Attributes Inspector,只需将“ 15”更改为0。对要更改的所有单元格执行此操作。

提示

您可能需要添加[cell setLayoutMargins:UIEdgeInsetsZero];tableViewCell


1
还是那很奇怪。这确实对我有用(谢谢!),在我要显示UITableViewCells的行上,但是在它们下面的任何空行上,分隔符仍然缩进15个像素。
迈克·格莱德希尔

如果您使用的是静态单元格,则只需将左插图更改为0,如图片中所述(在iOS 10中使用,Xcode 8.3.1)
Ignacio Valdivieso

29

对于Swift 3:

override func viewDidLoad() {
  super.viewDidLoad()

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

19

我继承UITableViewController了这两个inset设置,willDisplayCell并且还需要将它们设置preservesSuperviewLayoutMargins为false。在Swift中,它看起来像这样:

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

您无需进行设置,preservesSuperviewLayoutMargins = false因为默认值已经为false
crubio

2
请注意,如果您的单元格未填满整个高度,这将不会调整控制器显示的“占位符”单元格上的分隔符以填充单元格下方的视图。
蒂姆2015年


11

Inset默认情况下,分隔符从左起是15。将Separator Inset选项从更改autocustom,并将插图设置为0

在此处输入图片说明


9

对于iOS 9+中的Swift

如果使用自定义UITableViewCell

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

然后在您UITableViewviewDidLoad

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

这是唯一为我解决的问题(更新为快速3)。但是...当单元格中有数据时,它可以工作。对于尚未填充的空白单元格(我想还没有调用此替代的layoutMargins变量),分隔符仍无法填充表格视图中自定义单元格的全部宽度。有什么想法吗?
RanLearn '17

在iPhone上,分隔符在空白单元格的左端和右端仅几个像素处结束。如果不使用此技巧将边距清零,这看起来还不错。在iPad上,真正的问题是-空单元格上的分隔符从表格视图的左边缘开始,仅占单元格宽度的80%。当单元格中有数据时,分隔符仍然是单元格宽度的80%,但它以20%的方式开始,一直到
表格视图

1
找出解决方案...使用if #available(iOS 9,*){self.tableView.cellLayoutMarginsFollowReadableWidth = false}做到了这一点,因此我在iPhone上根本不需要您的代码。分隔符刚好全宽。在iPad上,空白单元格具有全角分隔符,但是我需要您的代码,以便在添加数据时保持全角。否则,向左添加一些像素,一旦数据填满单元格,该区域将没有分隔符。
RanLearn '17

1
回答我从上面的注释中获得代码的位置:stackoverflow.com/a/31538250/428981
RanLearns

9

对于iPad遇到问题的人–这将使您处于与iPhone相同的状态。然后,您可以separatorInset根据需要进行调整。

tableView.cellLayoutMarginsFollowReadableWidth = false

这是我在iOS 10和iOS 11上遇到的问题。iOS11很好,但是10有不同的边距。谢谢!!!
migs647 '18

9

cellForRowAtIndexPath方法中使用它,以配置单元格的分隔符规格,
非常适合iOS9.0 +

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

8

经过iOS 9.3和Swift 2.2的测试。确保willDisplayCell仅在显示单元之前将调用的代码放在其中,而不是仅在cellForRowAtIndexPath创建单元的位置。

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

添加override到的函数UITableViewController,如下所示:

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

5

在Swift 2.2和Xcode 7.3.1中,上述所有方法都不适合我

原来是所有方法中最简单的解决方案。无需代码。只需TableViewCellUITableView检查器中更改“ 布局边距”值即可:


4

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

1

viewDidLoad(经过测试的iOS11-Swift 4.1)

尝试

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


0

这些解决方案都无法在iPad上运行,但是我想出了一个涵盖两种设备的解决方案:

对于可重复使用的单元:

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

对于不可重复使用的单元:

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

只是为了扩展这种方法:

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

UITableView&可以使用这两个属性UITableViewCell。实际上,后者是的属性UIView,它是UITableView&的父类UITableViewCell


1
我为不可重复使用的电池找到了唯一可行的解​​决方案
Mickey,

0

迅速5,Xcode 11更新

放置在viewDidLoad()内部

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

对于边到边的分隔符,只需将left和right的值设置为0。

顺便说一句,将“ yourTableView”更改为tableView出口名称。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.