如何调整UITableView中原型单元格的左边距?

62
如果我通过Xcode的“文件→新建项目...→iOS→主细节应用程序”创建一个UITableViewController,则将创建一个带有原型单元格的UITableView

生成的视图层次结构如下:

UITableViewController视图层次结构

自动地在 Cell 的内容 UIView 左侧边缘和 "Title" 文本的 UILabel 元素之间创建了一个左侧的“边距”,如下所示:

Prototype cell gap

这导致在运行时设备的屏幕边缘和UILabel文本之间产生相应的边距:

Runtime gap

那么,这个间隙的宽度是在哪里设置的,如何进行调整呢?

UILabel大小检查器中的控件已被禁用:

输入图像说明

我的首选选项是能够在界面构建器中设置此间隙的宽度,但我也想了解此间隙的设置位置以及如何在编程上进行更改。

您正在使用自定义样式单元格还是基本样式? - Josh Valdivieso
@JoshValdivieso 基本的。以上内容直接来自于Xcode中默认的主从项目。 - j b
10个回答

57
你只需要设置表视图的 contentInset 属性,可以根据你的需求设置值。 self.tableView.contentInset = UIEdgeInsetsMake(0, -15, 0, 0); 输出结果


这个可行,谢谢!你知道在Interface Builder中是否可以设置contentInset吗? - j b
1
@JamieBullock... 是的,即使使用Interface Builder也是可能的。为此,请在IB中选择您的TableView>选择Identity Inspector(右侧-第3个选项)>通过单击加号(+)图标在User Defined Runtime Attributes中添加以下条目。 [详细信息:Keypath:contentInset,Type:Rect,Value:{{0,-15},{0,0}}] - MilanPanchal
35
我不认为这是一个好的解决方案。如果你这样做,会让你的UITableViewCell向左移动15个单位,并且单元格的右侧留有15单位的边距。 - Meilbn
1
我可以为不同的单元格分配不同的样式吗?而不是一个样式适用于所有单元格。 - H Raval
2
这将使内容向左移动15pt,并在iOS13上在右侧留下15pt的空间。 - leonardosccd

48

前往Main.storyboard > 选择UITableViewCell > 属性检查器。将分隔符下拉列表从默认间距更改为自定义间距。将左侧间距从15更改为0。

输入图像描述


2
在2019年的Xcode 10.x和iOS 12中,这仍然是使用Xcode的界面构建器完成此操作的正确方法。 - Mason

43

iOS 8 开始,可以使用单元格属性 layoutMargins。因此,在您的 tableView:cellForRowAtIndexPath 或自定义的 UITableViewCell 中调整单元格边距的正确方法是按以下方式设置此属性:

override func awakeFromNib() {
    super.awakeFromNib()

    self.layoutMargins = UIEdgeInsetsZero //or UIEdgeInsetsMake(top, left, bottom, right)
    self.separatorInset = UIEdgeInsetsZero //if you also want to adjust separatorInset
}

我希望这能对某人有所帮助。


3
我建议使用 self.contentView.layoutMargins = UIEdgeInsetsZero 可以达到预期的效果。至少对于我来说,因为我将所有视图与内容视图边距对齐。 - Andreas
1
我实际上将这些值添加到了UITableView本身,而不是单元格中,它在iOS 9.2上运行良好。 - Mike Gledhill
1
我想为不同的单元格设置不同的边距,请问您能否建议我如何做到这一点? - H Raval
1
从iOS 11开始,应该使用directionalLayoutMargins,如layoutMargins文档所述。 - Gobe

10

请按照下面链接中所述,在您的代码中添加该方法:

如何在不在右侧创建间隙的情况下消除UITableView左侧的边距?

该方法在Objective-C中如下:

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

Swift 3 和 4

public func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
    if cell.responds(to: #selector(setter: UITableViewCell.separatorInset)) {
        cell.separatorInset = .zero
    }
    if (cell.responds(to: #selector(setter: UIView.preservesSuperviewLayoutMargins))) {
        cell.preservesSuperviewLayoutMargins = false
    }

    if (cell.responds(to: #selector(setter: UIView.layoutMargins))) {
        cell.layoutMargins = UIEdgeInsets.zero
    }
    if tableView.responds(to: #selector(setter: UITableViewCell.separatorInset)) {
        tableView.separatorInset = .zero
    }
    
}

2
请包含您建议的实际代码/方法,而不仅仅是分享链接! - Paresh Mayani
1
这正是我在寻找的!谢谢。 - Paul Lehn

9
如果您在使用xib来创建单元格,请确保“相对于边缘”未被选中。您可以通过检查器来检查此设置,如下图所示:

enter image description here


2
如果你正在使用Storyboard和Nib文件,这将非常有用。 - Luiz Dias
这是唯一对我有效的答案。您必须选择受“contentView”约束的视图,并根据上面的图像更新其约束。 - PatPatchPatrick

6
在TableView的“属性检查器”中,将分割器插入设置为“自定义”,左侧为0。这就是你需要做的全部!

6
这会改变“分隔符”插图(例如用于表格组标题),但不影响单元格内容。将分隔符插图设置为 -> 左侧0,不会影响单元格内容视图左侧边缘与UILabel之间的空间。 - j b
你是正确的!但是,在你的情况下,你需要使用一个“自定义样式单元格”,并将表视图分隔符插入左侧=0。你可以注意到milanpanchal的截图右侧的分隔符和披露指标向左移动了15像素。 - Nicolai Nita
1
"自定义样式单元格" - 可让您将标签定位在所需位置,表视图分隔符插入左侧 = 0 - 将调整分隔符位置。 - Nicolai Nita
谢谢你提供的信息。实际上,我已经在我的项目中使用了自定义单元格。我提出这个问题的动机是想了解基本单元格布局的工作原理,@milanpanchal的回答表明边距来自于UITableViewcontentInset属性。 - j b

5
正如WTIFS所提到的,UITableViewCellindentation属性是在内置的单元格样式中缩进文本标签的好方法。只需像这样做就可以实现漂亮的左边距:
cell.indentationLevel = 2;

然而,这对于imageView并不起作用。


这将在单元格的文本标签上存档缩进级别,而不是整个单元格以及可选的图像视图。 - Munib
@return0 很不幸,这是真的。 为此添加一条注释。 - Dannie P
嗨,别担心。我发现最好的方法就是制作一个自定义UIViewCell。这几乎是最简单的选择,并具有更大的灵活性。 - Munib

3
这是Chetan答案的Swift版本:
override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
        tableView.separatorInset = UIEdgeInsets.zero
        tableView.layoutMargins = UIEdgeInsets.zero
        cell.preservesSuperviewLayoutMargins = false
        cell.layoutMargins = UIEdgeInsets.zero
        cell.separatorInset = UIEdgeInsets.zero
}

1
如果您只想更改单元格文本标签的左边距,则将nib文件中的水平间距约束“常数”更改为16或8,具体取决于您想要的填充量。如果您无法到达“常数”,请选择标签,在FrameRectangle视图中更改x坐标,然后单击左侧的约束引脚。 enter image description here

0

我想我刚刚想出了一个简单的解决方案。哈哈。

顶部答案有些问题...它减少了左边的间隙,但导致右边的间隙。

我在界面构建器中使用了约束

首先为表视图添加-15左边距约束

然后为表格单元格添加一些缩进,使内容看起来更好。


这是一些逐步图片: 添加约束条件。记得取消选中“与最近邻居的间距”。

Add the constraint. Remember to uncheck the "spacing to nearest neighbor".

表格单元格将向左移动。但似乎太靠近边缘了。

After adding the constraint

选择表格单元格,在右侧区域添加一些缩进。

add some indentation


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接