iOS 8 UITableView分隔符插入0不起作用


662

我有一个应用程序,其中UITableView的分隔符插入设置为自定义值-Right 0,Left 0。这在中可以完美使用iOS 7.x,但是在iOS 8.0我看到的分隔符插入设置为15右侧的默认值。即使在xib文件中将其设置为0,它仍然正确显示。

如何删除UITableViewCell分隔页边距?


您是否尝试将插图设置为0.001而不是0?我记得有一个类似的问题,边缘插入不会对0做出反应,但确实对0.001(或类似的小值)做出反应。
2014年

我试过了,也没有用..
user3570727 2014年

4
然后,我建议将分隔符颜色设置为[UIColor clearColor]并绘制自己的分隔符。这样您会更加灵活。
Freshking

1
我仍然无法相信这仍然不是UITableViewCellSeparatorStyle默认值之一。在我看来,即使是被接受的答案也是一个非常肮脏的技巧。
Enrico Susatyo 2014年

Answers:


1071

iOS 8.0在单元格和表视图上引入了layoutMargins属性。

此属性在iOS 7.0上不可用,因此您需要确保在分配前检查一下!

最简单的解决方法是对单元格进行子类化,并覆盖@ user3570727所建议的layout margins属性。但是,您将失去任何系统行为,例如从安全区域继承边距,因此我不建议您使用以下解决方案:

(目标C)

-(UIEdgeInsets)layoutMargins { 
     return UIEdgeInsetsZero // override any margins inc. safe area
}

(第4.2节):

override var layoutMargins: UIEdgeInsets { get { return .zero } set { } }

如果您不想覆盖该属性,或者需要有条件地对其进行设置,请继续阅读。


除了该layoutMargins属性外,Apple还向您的单元格添加了一个属性,以防止其继承表视图的边距设置。设置此属性后,将允许单元独立于表格视图配置其自身的边距。将其视为替代。

将此属性称为preservesSuperviewLayoutMargins,并将其设置为,NO将允许单元格的layoutMargin设置覆盖layoutMarginTableView上设置的任何内容。既节省时间(您不必修改表视图的设置),又更简洁。请参阅Mike Abdullah的答案以获取详细说明。

注意:下面是Mike Abdullah的回答所表示的单元格级边距设置的干净实现。设置单元格preservesSuperviewLayoutMargins=NO将确保您的表格视图不会覆盖单元格设置。如果您实际上希望整个表格视图具有一致的边距,请相应地调整代码。

设置您的单元格边距:

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

斯威夫特4:

func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
    // Remove seperator inset
    if cell.responds(to: #selector(setter: UITableViewCell.separatorInset)) {
        cell.separatorInset = .zero
    }
    // Prevent the cell from inheriting the Table View's margin settings
    if cell.responds(to: #selector(setter: UITableViewCell.preservesSuperviewLayoutMargins)) {
        cell.preservesSuperviewLayoutMargins = false
    }
    // Explictly set your cell's layout margins
    if cell.responds(to: #selector(setter: UITableViewCell.layoutMargins)) {
        cell.layoutMargins = .zero
    }
}

preservesSuperviewLayoutMargins单元格上的属性设置为NO 应该可以防止表格视图覆盖单元格边距。在某些情况下,它似乎无法正常运行。

如果全部失败,则可以强行使用Table View边距:

-(void)viewDidLayoutSubviews
{
    [super viewDidLayoutSubviews];

    // Force your tableview margins (this may be a bad idea)
    if ([self.tableView respondsToSelector:@selector(setSeparatorInset:)]) {
        [self.tableView setSeparatorInset:UIEdgeInsetsZero];
    }

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

斯威夫特4:

func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    // Force your tableview margins (this may be a bad idea)
    if tableView.responds(to: #selector(setter: UITableView.separatorInset)) {
        tableView.separatorInset = .zero
    }
    if tableView.responds(to: #selector(setter: UITableView.layoutMargins)) {
        tableView.layoutMargins = .zero
    }
}

...然后去!这应该可以在iOS 7和8上使用。


编辑: 穆罕默德·萨利赫(Mohamed Saleh)使我注意到了iOS 9中的可能更改。您可能需要将“表格视图”设置cellLayoutMarginsFollowReadableWidthNO如果要自定义插图或边距则。您的里程可能会有所不同,但记录不充分。

此属性仅在iOS 9中存在,因此请确保在设置前进行检查。

if([myTableView respondsToSelector:@selector(setCellLayoutMarginsFollowReadableWidth:)])
{
    myTableView.cellLayoutMarginsFollowReadableWidth = NO;
} 

斯威夫特4:

if myTableView.responds(to: #selector(setter: self.cellLayoutMarginsFollowReadableWidth)) {
    myTableView.cellLayoutMarginsFollowReadableWidth = false
}

(以上来自iOS 8 UITableView分隔符inset 0的代码不起作用

编辑:这是一个纯接口生成器方法:

TableViewAttributesInspector TableViewCellSizeInspector

注意:iOS 11更改并简化了许多这种行为,即将发布更新...


2
对于UIPopoverController内的表视图,我必须如上所述进行两项操作,而不仅仅是在willDisplayCell中进行。

44
我还发现,尽管上面有所有代码,但仍然必须cell.preservesSuperviewLayoutMargins = NO按照@bffmike的建议或在滚动显示方式后添加这些内容。(wtf ??)
inorganik

如果我们只想为分组的tableView中的一种类型的单元格设置边距怎么办?
SAHM 2014年

您可以尝试在willDisplayCell中设置它,看看它是否确实有效(您在单元格上有一个手柄,因此它应该是微不足道的)。如果没有,我们需要提交一个错误。国际海事组织,特定于单元的布局边缘应该是可能的。
cdstamper 2014年

2
这对我cell.preservesSuperviewLayoutMargins- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
有用

257

啊!在您的Cell子类中进行任一操作之后:

- (UIEdgeInsets)layoutMargins
{
    return UIEdgeInsetsZero;
}

cell.layoutMargins = UIEdgeInsetsZero;为我设置修复程序。


13
这个答案的第一个解决方案对我有用,第二个解决方案不起作用。
spybart 2014年

5
不要只使用cell.layoutMargins = UIEdgeInsetsZero; 因为它将在iOS 7.x上崩溃。最好在使用选择器之前先检查它是否存在。请参阅下面的我的解决方案。
Ricky 2014年

3
他没有设置cell.layoutMargins ...当您已经有自定义单元格时,此解决方案效果很好。
Sjoerd Perfors 2014年

11
这将在iOS 7中正常运行,因为该方法不会被调用!不过,您还需要设置表格视图的layoutMargins,否则它将无法正常工作。
cdstamper

2
覆盖访问器为我工作。但是所有其他解决方案都没有。即使separatorInset在IB中配置也不起作用。表格视图背景颜色也存在问题。这真是恶心的东西。
glasz 2014年

178

让我们花点时间来理解问题,然后再盲目尝试解决。

在调试器中快速浏览一下会发现分隔线是的子视图UITableViewCell。似乎单元本身对这些线的布局承担了相当大的责任。

iOS 8引入了布局边距的概念。默认情况下,视图的布局边距8pt在所有面上都是从祖先视图继承的

尽我们所知,在布置分隔线时,UITableViewCell选择尊重左侧布局边距,使用它来约束左侧插图。

将所有这些放在一起,以实现理想的真正零插入,我们需要:

  • 将左侧布局边距设置为 0
  • 停止所有继承该值的边距

这样,这是一个非常简单的任务:

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

注意事项:

  • 该代码仅需要在每个单元格中运行一次(毕竟,您只是在配置单元格的属性),并且选择执行它没有什么特别的地方。做对您来说最干净的事情。
  • 遗憾的是,这两个属性都无法在Interface Builder中进行配置,但是preservesSuperviewLayoutMargins如果需要,您可以指定用户定义的运行时属性。
  • 显然,如果您的应用程序也针对较早的OS版本,则需要避免执行上述代码,直到在iOS 8及更高版本上运行。
  • 除了设置之外preservesSuperviewLayoutMargins,您还可以将祖先视图(例如表格)配置为也有0左边距,但这似乎在本质上更容易出错,因为您无法控制整个层次结构。
  • 仅将左边距设置为剩余值,0而将其余值保留为原来的值,可能会稍微干净一些。
  • 如果您想UITableView在普通样式表底部绘制的“额外”分隔符上插入0 ,我想这也需要在表级别指定相同的设置(尚未尝试过此设置!)

3
谢谢!这确实是更简洁的答案。比重写两种方法并强行使用它要好得多。
LunaCodeGirl 2014年

16
在iOS 8中,对我而言,如果没有它就无法工作[self.tableView setSeparatorInset:UIEdgeInsetsMake(0, 0, 0, 0)];
davetw12 2014年

1
您投我一票,感谢您的明确解释。我只是要提到,在某些情况下,TableView本身还具有可能需要设置的layoutMargins,除了spacerInset之外。
cdstamper 2014年

@ davetw12和@cdstamper您能提供任何证据吗?到目前为止,我所有的探索都表明,设置单元格layoutMarginspreservesSuperviewLayoutMargins在单元格上都是必需的。还有什么感觉就像对伏都教的信任一样。
Mike Abdullah 2014年

3
不,这不是巫毒@MikeAbdullah的一种形式。为了让您避免默认separatorInsetUITableViewCelliOS中8,你要设定的设置UIEdgeInsets,以零上都UITableViewUITableViewCell。如果两者都不做,您的左插图仍然会大于零。我已经多次确认。
davetw12年

58

我相信这是我在这里问的相同问题:删除iOS 8的XTable 6 iPhone Simulator的SeparatorInset

iOS 8中,所有继承自的对象都有一个新属性UIView。因此,SeparatorInset在iOS 7.x中设置的解决方案将无法删除您在iOS 8的UITableView上看到的空白。

新属性称为“ layoutMargins ”。

@property(nonatomic) UIEdgeInsets layoutMargins
Description   The default spacing to use when laying out content in the view.
Availability  iOS (8.0 and later)
Declared In   UIView.h
Reference UIView Class Reference

iOS 8 UITableView setSeparatorInset:UIEdgeInsetsZero setLayoutMargins:UIEdgeInsetsZero

解决方案:-

-(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 ([cell respondsToSelector:@selector(setLayoutMargins:)]) {
        [cell setLayoutMargins:UIEdgeInsetsZero];
   }
}

如果您在cell.layoutMargins = UIEdgeInsetsZero;未检查是否layoutMargins存在的情况下进行设置,则该应用将在iOS 7.x上崩溃。因此,最好的方法是先检查layoutMargins之前是否存在setLayoutMargins:UIEdgeInsetsZero


如果部署目标设置为iOS 7,如何使用此方法?
Petar 2014年

我将tableView的代码放入viewDidLoad中,并且工作正常。我认为没有必要在willDisplayCell()中每次都调用它们。
阿卜杜拉·乌默尔

46

您可以在应用程序启动时(加载UI之前)使用UIAppearance一次,将其设置为默认全局设置:

// iOS 7:
[[UITableView appearance] setSeparatorStyle:UITableViewCellSeparatorStyleSingleLine];
[[UITableView appearance] setSeparatorInset:UIEdgeInsetsZero];

[[UITableViewCell appearance] setSeparatorInset:UIEdgeInsetsZero];

// iOS 8:
if ([UITableView instancesRespondToSelector:@selector(setLayoutMargins:)]) {

    [[UITableView appearance] setLayoutMargins:UIEdgeInsetsZero];
    [[UITableViewCell appearance] setLayoutMargins:UIEdgeInsetsZero];
    [[UITableViewCell appearance] setPreservesSuperviewLayoutMargins:NO];

}

这样,您可以保持UIViewController的代码干净,并且可以随时重写它。


41

iOS在单元格和表视图上引入了layoutMargins属性。

此属性在iOS 7.0中不可用,因此您需要确保在分配前检查一下!

但是,Apple 在您的单元格中添加了一个名为preservesSuperviewLayoutMargins属性,该属性将阻止它继承表视图的边距设置。这样,您的单元格可以独立于表格视图配置其自己的边距。将其视为替代。

此属性称为preservesSuperviewLayoutMargins,并将其设置为NO可以允许您使用自己单元格的layoutMargin设置覆盖Table View的layoutMargin设置。既节省时间(您不必修改表视图的设置),又更简洁。请参阅Mike Abdullah的答案以获取详细说明。

注意:正如Mike Abdullah的回答所表达的,这是正确的,不太混乱的实现;设置单元格的preservesSuperviewLayoutMargins = NO将确保您的表格视图不会覆盖单元格设置。

第一步-设置您的单元格边距:

/*
    Tells the delegate that the table view is about to draw a cell for a particular row.
*/
override func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell,
    forRowAtIndexPath indexPath: NSIndexPath)
{
    // Remove separator inset
    if cell.respondsToSelector("setSeparatorInset:") {
        cell.separatorInset = UIEdgeInsetsZero
    }

    // Prevent the cell from inheriting the Table View's margin settings
    if cell.respondsToSelector("setPreservesSuperviewLayoutMargins:") {
        cell.preservesSuperviewLayoutMargins = false
    }

    // Explictly set your cell's layout margins
    if cell.respondsToSelector("setLayoutMargins:") {
        cell.layoutMargins = UIEdgeInsetsZero
    }
}

将单元格上的preservesSuperviewLayoutMargins属性设置为NO 应该可以防止表格视图覆盖单元格边距。在某些情况下,它似乎无法正常运行。

第二步-仅当所有操作失败时,您才可以蛮力使用Table View边距:

/*
    Called to notify the view controller that its view has just laid out its subviews.
*/
override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()

    // Force your tableview margins (this may be a bad idea)
    if self.tableView.respondsToSelector("setSeparatorInset:") {
        self.tableView.separatorInset = UIEdgeInsetsZero
    }

    if self.tableView.respondsToSelector("setLayoutMargins:") {
        self.tableView.layoutMargins = UIEdgeInsetsZero
    }
}

...然后去!这应该可以在iOS 8和iOS 7上使用。

注意:我使用iOS 8.1和7.1进行了测试,我只需要使用此说明的第一步。

仅当在渲染的单元格下面有未填充的单元格时,才需要执行第二步。如果表大于表模型中的行数。不执行第二步将导致不同的分隔符偏移量。


1
您不需要在willDisplayCell方法中检查选择器,因为方法本身已经是iOS 8+,并且永远不会从较早版本中调用。
Rivera 2015年

38

在Swift中,它有点烦人,因为它layoutMargins是一个属性,因此您必须覆盖getter setter。

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

这将有效地将其设置为layoutMargins只读,在我看来,这很好。


只有此解决方案对我有用。而且我不需要在方法中添加其他行代码。我确实使用了自定义单元格。
拉米斯2014年

2
对于静态单元格,除了覆盖layoutMargins之外,您仍然需要将单元格的分隔符样式更改为“自定义插入”,并在情节提要中将左值设置为“ 0”。
hufeng03 2014年

22

对于iOS 9,您需要添加:

if([myTableView respondsToSelector:@selector(setCellLayoutMarginsFollowReadableWidth:)])
{
    myTableView.cellLayoutMarginsFollowReadableWidth = NO;
} 

有关更多详细信息,请参阅问题


12
为每个版本添加一些代码以使初始外观保持不变很有趣……
Christian

20

Swift 2.0扩展

我只想共享一个扩展,以删除tableview单元格分隔符的空白。

extension UITableViewCell {
    func removeMargins() {

        if self.respondsToSelector("setSeparatorInset:") {
            self.separatorInset = UIEdgeInsetsZero
        }

        if self.respondsToSelector("setPreservesSuperviewLayoutMargins:") {
            self.preservesSuperviewLayoutMargins = false
        }

        if self.respondsToSelector("setLayoutMargins:") {
            self.layoutMargins = UIEdgeInsetsZero
        }
    }
}

在上下文中使用:

    let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! CustomCell

    cell.removeMargins()
    return cell

15

迅速:

override func viewDidLoad() {
    super.viewDidLoad()

    if self.tableView.respondsToSelector("setSeparatorInset:") {
        self.tableView.separatorInset = UIEdgeInsetsZero
    }
    if self.tableView.respondsToSelector("setLayoutMargins:") {
        self.tableView.layoutMargins = UIEdgeInsetsZero
    }

    self.tableView.layoutIfNeeded()            // <--- this do the magic
}

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
     ...

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

    return cell
}

11

我通过以下方式使其工作:

tableView.separatorInset = UIEdgeInsetsZero;
tableView.layoutMargins = UIEdgeInsetsZero;
cell.layoutMargins = UIEdgeInsetsZero;

9

至于cdstamper提出的建议而不是表格视图,在单元格的layoutSubview方法中添加以下行对我有用。

- (void)layoutSubviews 
{
    [super layoutSubviews];

    if ([self respondsToSelector:@selector(setSeparatorInset:)])
                [self setSeparatorInset:UIEdgeInsetsZero];

        if ([self respondsToSelector:@selector(setPreservesSuperviewLayoutMargins:)])
        {
            [self setPreservesSuperviewLayoutMargins:NO];;
        }

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

9

Swift 3.0示例:

func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
    // removing seperator inset
    if cell.responds(to: #selector(setter: UITableViewCell.separatorInset)) {
        cell.separatorInset = .zero
    }
    // prevent the cell from inheriting the tableView's margin settings
    if cell.responds(to: #selector(setter: UIView.preservesSuperviewLayoutMargins)) {
        cell.preservesSuperviewLayoutMargins = false
    }
    // explicitly setting cell's layout margins
    if cell.responds(to: #selector(setter: UITableViewCell.layoutMargins)) {
        cell.layoutMargins = .zero
    }
}

9

经过大量调查...

这是完全控制这些东西的唯一方法(我可以找到)

为了完全控制每个单元上的分隔符插图和布局边距。按照willDisplayCell您的方法执行此操作UITableviewDelegate

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

单元格对象控制分隔符,并contentView控制其他所有内容。如果分隔符插入空间以意外的颜色显示,则应解决该问题:

cell.backgroundColor = cell.contentView.backgroundColor

8

在简单的解决方案斯威夫特对于iOS 8的使用自定义UITableViewCell

override func awakeFromNib() {
    super.awakeFromNib()

    self.layoutMargins = UIEdgeInsetsZero
    self.separatorInset = UIEdgeInsetsZero
}

这样你设置layoutMarginseparatorInset只是一个时间,而不是做它的每一个willDisplayCell作为最上面的答案的建议。

如果您使用的是自定义,UITableViewCell这是正确的选择。否则,您应该在中进行tableView:cellForRowAtIndexPath

只是另一个提示:您无需进行设置,preservesSuperviewLayoutMargins = false因为默认值已经存在NO


8

对我来说,简单的工作就完成了

cell.layoutMargins = UIEdgeInsetsZero

在cellForRowAtIndexPath委托方法中调用了此方法。好的答案:)
圣徒贾布

7

只需添加以下代码即可解决此程序。

祝你好运!

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

}

5

Lukasz在Swift中回答:

    // iOS 7:
    UITableView.appearance().separatorStyle = .SingleLine
    UITableView.appearance().separatorInset = UIEdgeInsetsZero
    UITableViewCell.appearance().separatorInset = UIEdgeInsetsZero

    // iOS 8:
    if UITableView.instancesRespondToSelector("setLayoutMargins:") {
        UITableView.appearance().layoutMargins = UIEdgeInsetsZero
        UITableViewCell.appearance().layoutMargins = UIEdgeInsetsZero
        UITableViewCell.appearance().preservesSuperviewLayoutMargins = false
    }

5

这是在Swift中对我有用的代码:

override func viewDidLoad() 
{
    super.viewDidLoad()
    ...
    if tableView.respondsToSelector("setSeparatorInset:") {
        tableView.separatorInset = UIEdgeInsetsZero
    }
}

func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell,forRowAtIndexPath indexPath: NSIndexPath)
{
    if cell.respondsToSelector("setSeparatorInset:") {
        cell.separatorInset.left = CGFloat(0.0)
    }
    if tableView.respondsToSelector("setLayoutMargins:") {
        tableView.layoutMargins = UIEdgeInsetsZero
    }
    if cell.respondsToSelector("setLayoutMargins:") {
        cell.layoutMargins.left = CGFloat(0.0)
    }
}

对我而言,这似乎是最干净的(因为目前),因为所有cell / tableView边缘/边距调整都是在tableView:willDisplayCell:forRowAtIndexPath:方法中完成的,而无需将不必要的代码塞入tableView:cellForRowAtIndexPath:

顺便说一句,我只设置单元格的左eparatorInset / layoutMargins,因为在这种情况下,我不想搞砸我在单元格中设置的约束。

代码已更新为Swift 2.2:

 override func viewDidLoad() {
   super.viewDidLoad()       

    if tableView.respondsToSelector(Selector("setSeparatorInset:")) {
      tableView.separatorInset = UIEdgeInsetsZero
        }
    }

 override func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell,forRowAtIndexPath indexPath: NSIndexPath) {
        if cell.respondsToSelector(Selector("setSeparatorInset:")) {
            cell.separatorInset.left = CGFloat(0.0)
        }
        if tableView.respondsToSelector(Selector("setLayoutMargins:")) {
            tableView.layoutMargins = UIEdgeInsetsZero
        }
        if cell.respondsToSelector(Selector("setLayoutMargins:")) {
            cell.layoutMargins.left = CGFloat(0.0)
        }
    }

到底什么对您不起作用?刚刚在安装了iOS 8.1 SDK的iPhone 5模拟器上测试了此代码,一切都与我最初发布此答案时的状态相同。代码是使用Xcode 6.1.1编译和运行的。
伊万

4

大多数答案都呈现分离的插图和布局的利润被设置了多种方法(即viewDidLayoutSubviewswillDisplayCell细胞和tableviews等),但我发现,只是把这些在cellForRowAtIndexPath伟大的作品。似乎是最干净的方法。

// kill insets for iOS 8
if ([[UIDevice currentDevice].systemVersion floatValue] >= 8) {
    cell.preservesSuperviewLayoutMargins = NO;
    [cell setLayoutMargins:UIEdgeInsetsZero];
}
// iOS 7 and later
if ([cell respondsToSelector:@selector(setSeparatorInset:)])
    [cell setSeparatorInset:UIEdgeInsetsZero];

4

使用以下代码片段可避免在IOS 8和7中出现UITableView不必要的填充问题。

-(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 ([cell respondsToSelector:@selector(setLayoutMargins:)])
    {
        [cell setLayoutMargins:UIEdgeInsetsZero];
    }
}

4

我建议不要在每次更新时都进行更新preservesSuperviewLayoutMargins,而是建议layoutMargins每次在willDisplayCell中执行一次cellForRowAtIndexPath:

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

    let cell = super.tableView(tableView, cellForRowAtIndexPath: indexPath)

    cell.preservesSuperviewLayoutMargins = false
    cell.layoutMargins = UIEdgeInsetsZero

    return cell

}

4

这是一种全局删除插图的简单方法。

UITableViewCell+Extensions.swift

import UIKit

extension UITableViewCell {

  override public var layoutMargins: UIEdgeInsets {
    get { return UIEdgeInsetsZero }
    set { }
  }

}

AppDelegate application:didFinishLaunchingWithOptions:

  UITableViewCell.appearance().separatorInset = UIEdgeInsetsZero

您可能会认为a)也只是separatorInset在扩展名中覆盖,或b)layoutMargins而是为设置外观代理。两者都不起作用。即使separatorInset指示为属性,尝试将其作为属性(或方法)覆盖也会产生编译器错误。和设置外观代理UITableViewCelllayoutMargins(或者,对于这个问题,还设置外观为代理UITableViewlayoutMarginsseparatorInset)没有任何影响。


3

在iOS8中:

将此添加到我的UITableViewCell子类中:

- (UIEdgeInsets)layoutMargins {
    return UIEdgeInsetsZero;
}

这是“ tableView:cellForRowAtIndexPath”或“ tableView:willDisplayCell”:

[editCell setSeparatorInset:UIEdgeInsetsZero];

为我工作。


2
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
        // ... Get the cell
        cell.separatorInset = UIEdgeInsetsMake(0.f, 20.f, 0.f, [UIScreen mainScreen].bounds.size.width - 20);
        // others
        return cell;
}

对于任何特定的单元格,您要隐藏分隔符。


2

在看完第3层的答案之后,我试图弄清楚在TableView和TableViewCell之间设置分隔符的关系,并进行了一些测试。这是我的结论:

  1. 我们可以考虑将单元格的分隔符设置为零必须分两步移动分隔符:第一步是将单元格的spacerinset设置为零。第二步是将像元的marginlayout设置为零。

  2. 设置的TableView的separatorinsetmarginlayout可以影响细胞的separatorinset。然而,从测试,我发现的TableView的separatorinset似乎是无用的,TableView中的marginlayout实际上可以影响细胞的marginlayout

  3. 设置Cell的PreservesSuperviewLayoutMargins = false,可以切断TableView 对Cell 的marginlayout效果。

  4. 解决方案之一:

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        var cell = UITableViewCell()
    
        cell.preservesSuperviewLayoutMargins = false
        cell.separatorInset = UIEdgeInsetsZero
        cell.layoutMargins = UIEdgeInsetsZero
    
        return cell
    }

2

这是我的解决方案。这适用于自定义单元格子类,只需将它们都添加到子类中。

  1. - (UIEdgeInsets)layoutMargins {    
        return UIEdgeInsetsMake(0, 10, 0, 10);
    }

2。

self.separatorInset = UIEdgeInsetsMake(0, 10, 0, 10);

而且,您可以方便地自定义分隔符的位置,而无需要求设计师为您绘制一个……..


1

比最投票的答案更紧凑的方式...

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {

    if ([cell respondsToSelector:@selector(setSeparatorInset:)] && [cell respondsToSelector:@selector(setPreservesSuperviewLayoutMargins:)] && [cell respondsToSelector:@selector(setLayoutMargins:)]) {
         [cell setSeparatorInset:UIEdgeInsetsZero];
         [cell setPreservesSuperviewLayoutMargins:NO];
         [cell setLayoutMargins:UIEdgeInsetsZero];
    }

}


1

添加此代码段后,Swift中简单优雅的代码在iOS8中对我有效:)

    // tableview single line
func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
    cell.preservesSuperviewLayoutMargins = false
    cell.layoutMargins = UIEdgeInsetsZero
}

1

这对我在iOS 8和iOS 9中非常有效。

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