ChatGPT解决这个技术问题 Extra ChatGPT

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

我有一个 UITableView,其中分隔符没有全宽。它在左侧前 10 个像素处结束。我在 viewDidLoad() 中玩弄这段代码。

self.tableView.layoutMargins = UIEdgeInsetsZero;

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

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

UITableView 有一个属性 separatorInset。将UITableView行分隔符的插入设置为零。您也可以从情节提要中更改 separatorInset

S
SwiftiSwift

这适用于使用 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
}

斯威夫特 5 更新:

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

为什么这会删除我的空白表?分隔符已移动,但我看不到任何按钮
@James 你能解释一下“用一张空白的桌子删除我的桌子吗?”。您是如何添加按钮的(通过 IB、代码)?
非常好的解决方案。但在我的情况下,我将代码直接放入单元初始化中,因为我希望在所有控制器中都有全宽分隔符。
如果不是很明显,这当然也适用于具有适当语法更改的 Objective-C。
这些解决方案都不适用于 iPad。这仅适用于iPhone...
K
Kuldeep

在您的 UITableViewCell

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

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

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


或者这很奇怪。这确实对我有用(谢谢!)在我要显示 UITableViewCells 的行上,但在它们下面的任何空行上,分隔符仍然缩进 15 个像素。
如果您使用的是静态单元格,您只需将左插图更改为 0,如图中所述(在 iOS 10 中工作,Xcode 8.3.1)
N
Nilanshu Jaiswal

我从这篇文章中得到了答案:iOS 8 UITableView separator inset 0 not working

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

它适用于我只添加 tableView 委托方法
对不起,我不明白。您的意思是添加 TableViewDeleagte 就足够了?我只是尝试添加它对我不起作用@TonyTony
对我来说,方法 viewDidLayoutSubviews 不是必需的
您是否尝试使用 8 以外的 IOS 版本运行您的代码?也许它适用于最新的。否则对你有好处,它可以工作。我尝试仅添加 tableview 委托方法,但没有帮助。 @TonyTony
我不得不同时使用两者。我尝试单独使用每个都没有成功。仅当我同时使用两者时才有效。另外,当我的视图控制器是 UITableViewController 的子类,当它是 UIViewController 的子类时,我尝试过。没有不同。请注意,我在 8.1 模拟器中运行。
W
Wilson

对于斯威夫特 3:

override func viewDidLoad() {
  super.viewDidLoad()

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

N
Nilanshu Jaiswal

选择您的 UITableViewCell 转到属性检查器 转到分隔符并将其更改为“自定义插入”设置左侧和/或右侧字段。 (默认左:15,右:0)

看看它是如何工作的(使用 left: 100):

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

结果:

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


与@Hannah Louisa Carney 之前的回答重复
N
Nilanshu Jaiswal

我从 UITableViewController 继承,并且还需要在 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
请注意,如果您的单元格不构成完整高度,这不会调整控制器显示的“占位符”单元格上的分隔符以填充单元格下方的视图。
A
Ali

分隔符 Inset 默认为左起 15。将分隔符 Inset 选项从 auto 更改为 custom 并将插入设置为 0

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


N
Nilanshu Jaiswal

对于 iOS 9+ 中的 Swift

如果使用自定义 UITableViewCell

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

然后对于 viewDidLoad 中的 UITableView

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

这是为我修复它的唯一答案(更新为 swift 3)。但是......当单元格中有数据时它可以工作。对于尚未填充的空白单元格(我猜还没有调用此覆盖的 layoutMargins 变量),分隔符仍然没有填充表格视图中我的自定义单元格的整个宽度。有什么想法吗?
在 iPhone 上,分隔符在空单元格的左侧和右侧几个像素处结束。如果不使用此技巧将边距归零,这看起来还不错。在 iPad 上是真正的问题 - 空单元格上的分隔符从 tableview 的左边缘开始,只有大约 80% 的单元格宽度。当单元格中有数据时,分隔符仍然是单元格宽度的 80%,但它从 20% 处开始,一直到 tableview 的右边缘
想出了一个解决方案......使用 if #available(iOS 9, *) { self.tableView.cellLayoutMarginsFollowReadableWidth = false } 做到了,所以我在 iPhone 上根本不需要你的代码。分隔符只是全宽。在 iPad 上,空单元格有一个全宽分隔符,但我需要您的代码以便在添加数据时保持全宽。否则,一旦数据填充单元格,就会在没有分隔符的左侧添加几个像素。
回答我从哪里获得上述评论中的代码:stackoverflow.com/a/31538250/428981
N
Nilanshu Jaiswal

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

tableView.cellLayoutMarginsFollowReadableWidth = false

这是我在 iOS 10 与 iOS 11 上的问题。iOS 11 很好,但 10 有不同的边距。谢谢!!!
A
Ash

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

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

N
Nilanshu Jaiswal

测试 iOS 9.3 &斯威夫特 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) {

D
Developersian

斯威夫特 5,Xcode 11 更新

把它放在 viewDidLoad() 里面

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

对于边到边分隔符,只需将左右的值设置为 0。

顺便将“yourTableView”更改为您的 tableView 插座名称。


Swift 5 你可以简单使用UIEdgeInsets.zero
K
Kuldeep

以上方法在 Swift 2.2 和 Xcode 7.3.1 中都不适合我

原来是最简单的解决方案。无需代码。只需在 UITableView 检查器中更改 TableViewCell Layout Margins 值:

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


N
Nilanshu Jaiswal

对于斯威夫特 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

viewDidLoad(测试 iOS11 - swift 4.1)

尝试

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


K
Kuldeep

这些解决方案都不适用于 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 的一个属性,它是 UITableViewUITableView 的父类。 UITableViewCell


我为不可重复使用的细胞找到的唯一可行的解决方案