iOS 8 UITableView разделитель inset 0 не работает

у меня есть приложение, где UITableView's разделитель вставка имеет настраиваемые значения-Right 0, слева 0. Это прекрасно работает в iOS 7.x, однако в iOS 8.0 Я вижу, что вставка разделителя установлена по умолчанию 15 справа. Хотя в xib файлы для 0, он по-прежнему отображается неправильно.

Как убрать UITableViewCell поля сепаратора?

30 ответов


iOS 8.0 представляет свойство layoutMargins для ячеек и представлений таблиц.

это свойство недоступно в iOS 7.0, поэтому перед назначением его необходимо проверить!

кроме того, Apple добавила в свойства в вашу ячейку, которая предотвратит наследование настроек маржи вашего представления таблицы. Если это свойство задано, ячейкам разрешается настраивать собственные поля независимо от представления таблицы. Думайте об этом как о переопределении.

это свойство называется preservesSuperviewLayoutMargins, и установка его в NO позволит ячейки layoutMargin настройка для переопределения любого layoutMargin установлен на вашем TableView. Это экономит время (вам не нужно изменять настройки представления таблицы), и является более кратким. Пожалуйста, обратитесь к ответу Майка Абдуллы за подробным объяснением.

Примечание: ниже приведена чистая реализация для маржа на уровне ячейки настройка, как выражается в ответе Майка Абдуллы. Установка параметра 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];
    }
}

Swift 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 собственность на ваш сотовый нет должны запретить переопределение полей ячеек в представлении таблицы. В некоторых случаях он, кажется, не функционирует должным образом.

если все терпит неудачу, вы можете грубо заставить свои поля представления таблицы:

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

Swift 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.

EDIT: Мохаммед Салех обратил мое внимание на возможное изменения в iOS 9. вам может потребоваться установить вид таблицы cellLayoutMarginsFollowReadableWidth to NO если вы хотите настроить вкладки или поля. Ваш пробег может отличаться, это не очень хорошо документировано.

это свойство существует только в iOS 9, поэтому обязательно проверьте перед установкой.

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

Swift 4:

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

(выше код iOS 8 UITableView разделитель inset 0 не работает)

EDIT: вот чистый Подход к построителю интерфейса:

TableViewAttributesInspector TableViewCellSizeInspector

Примечание: iOS 11 изменяет и упрощает большую часть этого поведения, обновление будет доступно...


Arg!!! После игры вокруг либо делать это в вашем Cell подкласс:

- (UIEdgeInsets)layoutMargins
{
    return UIEdgeInsetsZero;
}

или задание cell.layoutMargins = UIEdgeInsetsZero; исправлено для меня.


давайте возьмем момент, чтобы понять проблему, прежде чем слепо заряжаться, чтобы попытаться исправить это.

быстрый поиск в отладчике скажет вам, что разделительные линии являются подвидами UITableViewCell. Похоже, что сама ячейка берет на себя изрядную долю ответственности за компоновку этих линий.

iOS 8 вводит концепцию поля макета. По умолчанию, поля макета представления,8pt со всех сторон, и они унаследовала вид предка.

как лучше всего мы можем сказать, выкладывая свою линию сепаратора,UITableViewCell выбирает уважать левое поле макета, используя его для ограничения левой вставки.

собирая все это вместе, чтобы достичь желаемой вставки действительно нуля, нам нужно:

  • установите левое поле макета в 0
  • остановить любые унаследованные поля, переопределяющие это

вот так, это довольно простая задача для достижения:

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

Примечание:

  • этот код должен для запуска один раз в ячейку (вы просто настраиваете свойства ячейки в конце концов), и нет ничего особенного, когда вы решаете выполнить его. Делай то, что кажется тебе самым чистым.
  • к сожалению, ни одно свойство не доступно для настройки в Interface Builder, но вы можете указать пользовательский атрибут времени выполнения для preservesSuperviewLayoutMargins если желанный.
  • ясно, что если ваше приложение нацелено на более ранние версии ОС, вам нужно будет избегать выполнения вышеуказанного кода до запуска на iOS 8 и выше.
  • вместо preservesSuperviewLayoutMargins, вы can настроить представления предков (например, таблицу), чтобы иметь 0 левое поле тоже, но это кажется по своей сути более подверженным ошибкам, поскольку вы не контролируете всю эту иерархию.
  • вероятно, было бы немного чище установить только левое поле в 0 и оставь остальных в покое.
  • если вы хотите иметь вставку 0 на" дополнительных " сепараторах, которые UITableView рисует в нижней части таблиц обычного стиля, я предполагаю,что потребуется указать те же настройки на уровне таблицы (не пробовал это!)

Я считаю, что это один и тот же вопрос, который я задал здесь: удалить SeparatorInset на iOS 8 UITableView для Xcode 6 iPhone Simulator

на iOS 8 есть одно новое свойство для всех объектов, наследующих от UIView. Итак, решение установить SeparatorInset в iOS 7.x не сможет удалить пробел, который вы видите на UITableView в iOS 8.

вызывается новое свойство "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. Таким образом, лучшим способом было бы проверить, если прежде, чем setLayoutMargins:UIEdgeInsetsZero.


вы можете использовать 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 чистым и всегда можете переопределить его, если хотите.


Swift версия

iOS представляет свойство layoutMargins для ячеек и представлений таблиц.

это свойство недоступно в iOS 7.0, поэтому вам нужно убедиться, что вы проверяете перед его назначением!

тем не менее, Apple добавила свойства под названием preservesSuperviewLayoutMargins к вашей ячейке, которая предотвратит ее наследование настроек маржи вашего представления таблицы. Таким образом, ваши ячейки могут настроить свои собственные поля независимо от представления таблицы. Думайте об этом как о переопределении.

это свойство называется preservesSuperviewLayoutMargins, и установка его в NO может позволить вам переопределить настройки layoutMargin вашего представления таблицы с настройкой layoutMargin вашей собственной ячейки. Это экономит время (вам не нужно изменять настройки представления таблицы), и является более кратким. Пожалуйста, обратитесь к ответа Майк Абдуллы подробное объяснение.

Примечание: это правильная, менее грязная реализация, как выражено в ответе Майка Абдуллы; установка вашей ячейки 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 в ячейке в значение нет должны запретить переопределение представления таблицы поля ячейки. В некоторых случаях он, кажется, не функционирует должным образом.

второй шаг-только если все терпит неудачу, вы можете грубо принудить поля представления таблицы:

/*
    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, в моем случае мне нужно использовать только первый шаг этого объяснения.

второй шаг требуется только в том случае, если под отображаемой ячейкой имеется незаселенная ячейка клетки, т. е. если таблица больше, чем количество строк в модели таблицы. Не выполнение второго шага приведет к различным смещениям разделителя.


в Swift это немного более раздражает, потому что layoutMargins является свойством, поэтому вы должны переопределить getter и сеттер.

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

Это будет эффективно сделать layoutMargins только для чтения, что в моем случае нормально.


для iOS 9 вам нужно добавить:

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

для больше деталей пожалуйста см. вопрос.


Расширение 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

Swift:

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
}

Я сделал это, сделав это:

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

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

после долгих исследований...

вот единственный способ полностью контролировать этот материал (который я мог найти)

для полного управления вставками разделителей и полями макета в каждой ячейке. Сделайте это в 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

для меня простая строка сделала работу

cell.layoutMargins = UIEdgeInsetsZero

Что касается того, что предложил 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];
        }
}

простое решение Свифт на iOS 8 с пользовательским UITableViewCell

override func awakeFromNib() {
    super.awakeFromNib()

    self.layoutMargins = UIEdgeInsetsZero
    self.separatorInset = UIEdgeInsetsZero
}

таким образом, вы настраиваете layoutMargin и separatorInset только один раз вместо того, чтобы делать это для каждого willDisplayCell как и большинство из приведенных выше ответов.

если вы используете пользовательские UITableViewCell это правильное место для этого. В противном случае вы должны сделать это в tableView:cellForRowAtIndexPath.

еще один намек: вам не нужно устанавливать preservesSuperviewLayoutMargins = false потому что значение по умолчанию уже NO!


просто добавьте ниже код может решить эту программу.

удачи вам!

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

}

используйте ниже фрагмент кода, чтобы избежать нежелательной проблемы заполнения для UITableView в IOS 8 & 7.

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

это код, который работает для меня, в 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)
    }
}

Это кажется мне самым чистым (на данный момент), так как все настройки ячейки/tableView edge/margin выполняются в tableView:willDisplayCell:forRowAtIndexPath: метод, без зубрежки ненужного кода в tableView:cellForRowAtIndexPath:.

кстати, я только устанавливаю левый separatorInset/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)
        }
    }

большинство ответов показывают вставки разделителя и поля макета, установленные по различным методам (т. е. viewDidLayoutSubviews, willDisplayCell и т. д.) Для ячеек и табличных представлений, но я обнаружил, что просто помещаю их в 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];

вместо обновления 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

}

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
    }

в iOS8:

добавление этого в мой подкласс UITableViewCell:

- (UIEdgeInsets)layoutMargins {
    return UIEdgeInsetsZero;
}

и это для "tableView: cellForRowAtIndexPath" или "tableView:willDisplayCell":

[editCell setSeparatorInset:UIEdgeInsetsZero];

работал на меня.


вот простой способ глобального удаления вставки.

на 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 (или, если на то пошло, также настройка прокси внешний вид UITableView ' s layoutMargins и separatorInset) не имеет никакого эффекта.


после того, как я увидел ответы на этаже 3, я попытался выяснить, какова связь настройки разделителя между TableView & TableViewCell и сделал некоторый тест. Вот мои выводы:--2-->

  1. мы можем считать, что установка разделителя ячейки на ноль должна переместить разделитель в два шага: первый шаг-установить ячейку separatorinset к нулю. второй шаг-установить ячейку marginlayout в нуль.

  2. установить TableView в separatorinset и marginlayout может повлиять на separatorinset. Однако из теста я обнаружил, что TableView separatorinset кажется бесполезным, TableView marginlayout может фактически повлиять на marginlayout.

  3. установить ячейку PreservesSuperviewLayoutMargins = false, можно отключить TableView marginlayout эффект на клетки.

  4. одно из решений:

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

Это мое решение. Это относится к подклассу пользовательских ячеек, просто добавьте их в подкласс.

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

2.

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

и удобно что вы можете подгонять положение разделителя без просить ваш конструктор нарисовать одно для вас..........


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

для каждой конкретной ячейки, которую вы хотите скрыть разделитель.


более компактным способом, чем самый проголосовавший ответ...

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

}


добавление этого фрагмента, простой элегантный в Swift работает для меня в iOS8:)

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

это отлично сработало для меня в 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;
    }