it-swarm.com.ru

Вставка разделителя UITableView в iOS 8 не работает

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

Как удалить поля разделителя UITableViewCell?

655
user3570727

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

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

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

РЕДАКТИРОВАТЬ: Мохамед Салех обратил мое внимание на возможное изменение в iOS 9. Вам может потребоваться установить cellLayoutMarginsFollowReadableWidth в табличном представлении на NO, если вы хотите настроить вставки или поля. Ваш пробег может варьироваться, это не очень хорошо задокументировано.

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

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

Swift 4:

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

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

РЕДАКТИРОВАТЬ: Вот чистый подход Interface Builder:

TableViewAttributesInspectorTableViewCellSizeInspector

ПРИМЕЧАНИЕ: iOS 11 изменяет и упрощает большинство из этих действий, будет обновление ...

1068
cdstamper

Arg !!! После того, как вы поиграете, сделайте это в своем подклассе Cell:

- (UIEdgeInsets)layoutMargins
{
    return UIEdgeInsetsZero;
}

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

255
user3570727

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

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

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

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

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

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

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

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

Что следует отметить:

  • Этот код только необходимо запускается один раз для каждой ячейки (в конце концов, вы просто настраиваете свойства ячейки), и нет ничего особенного в том, когда вы решите его выполнить. Делай то, что кажется тебе наиболее чистым.
  • К сожалению, ни одно из свойств не доступно для настройки в Интерфейсном Разработчике, но вы можете указать пользовательский атрибут времени выполнения для preservesSuperviewLayoutMargins при желании.
  • Очевидно, что если ваше приложение предназначено и для более ранних выпусков ОС, вам нужно избегать выполнения приведенного выше кода до тех пор, пока оно не будет запущено на iOS 8 и выше.
  • Вместо того, чтобы устанавливать preservesSuperviewLayoutMargins, вы можете настроить представления предков (например, таблицу), чтобы иметь также левое поле 0, но это по своей природе более подвержено ошибкам, поскольку вы не контролируете всю эту иерархию.
  • Вероятно, было бы немного чище установить для 0 только левое поле и оставить остальные.
  • Если вы хотите, чтобы в "лишних" разделителях, которые UITableView отображал в нижней части таблиц простых стилей, была вставка 0, я предполагаю, что для этого потребуется указать те же настройки на уровне таблицы (еще не пробовал!)
178
Mike Abdullah

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

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

58
Ricky

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

46
Lukasz

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

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

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

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

ПРИМЕЧАНИЕ: это правильная, менее запутанная реализация, как выражено в ответе Майка Абдуллы; установка preservSuperviewLayoutMargins = 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
    }
}

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

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

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

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

41
King-Wizard

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

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

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

38
swilliams

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

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

Для более подробной информации, пожалуйста, обратитесь к вопрос .

22
Julian Król

Расширение Swift 2.0

Я просто хотел поделиться расширением, которое я сделал, чтобы удалить поля из разделителей ячеек таблицы.

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
20
Dan Beaulieu

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
}
15
Alexander Volkov

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

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

пример 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
mkz

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

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

Для полного контроля как вкладышей разделителя, так и полей макета в каждой ячейке. Сделайте это с помощью метода 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
9
Matjan

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

Простое решение в Swift для iOS 8 с пользовательским UITableViewCell

override func awakeFromNib() {
    super.awakeFromNib()

    self.layoutMargins = UIEdgeInsetsZero
    self.separatorInset = UIEdgeInsetsZero
}

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

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

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

8
Francesco Vadicamo

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

cell.layoutMargins = UIEdgeInsetsZero
8
apinho

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

Удачи тебе!

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

}
7
JimmyChang

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

Это кажется мне наиболее чистым (на данный момент), так как все настройки Edge/margin элемента cell/tableView выполняются в методе 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)
        }
    }
5
Ivan

Ответ Лукаша в Свифте:

    // 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
Naka

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

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

Используйте приведенный ниже фрагмент кода, чтобы избежать нежелательной проблемы с заполнением для 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];
    }
}
4
Anooj VM

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

В UITableViewCell+Extensions.Swift:

import UIKit

extension UITableViewCell {

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

}

В AppDelegateapplication:didFinishLaunchingWithOptions::

  UITableViewCell.appearance().separatorInset = UIEdgeInsetsZero

Вы можете подумать, чтобы а) также просто переопределить separatorInsetв расширении, или б) вместо этого установить прокси внешнего вида для layoutMarginsname__. Ни один не будет работать. Даже если separatorInsetуказано как свойство, попытка переопределить его как свойство (или метод) приводит к ошибкам компилятора. И установка прокси внешнего вида для UITableViewCellname __ layoutMargins(или, в этом отношении, также установка прокси внешнего вида для UITableViewname __ 'layoutMarginsи separatorInsetname__) не имеет никакого эффекта.

3
Scott Gardner

В iOS8:

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

- (UIEdgeInsets)layoutMargins {
    return UIEdgeInsetsZero;
}

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

[editCell setSeparatorInset:UIEdgeInsetsZero];

Работал для меня.

3
CoderSaru
-(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
xmurobi

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

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

2.

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

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

2
Guoyu

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

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

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

  3. set PresesSuperviewLayoutMargins = Cell, может обрезать эффект 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
    }
    
2
Xin Chen

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

- (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
subharb

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

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

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

Мое решение - добавить UIView в качестве контейнера для подпредставлений ячейки. Затем установите ограничения UIView (верх, низ, трейлинг, ведущий) в 0 пунктов. И вся ненужная масса уходит . изображение, показывающее логику

0
memetcircus

Мне не повезло ни с одним из решений выше. Я использую файлы NIB для ячеек своих таблиц. Я "исправил" это, добавив метку высотой 1. Я изменил фон метки на черный, прикрепил метку к нижней части пера, а затем прикрепил нижнюю часть остального содержимого к добавленной метке. , Теперь у меня есть черная рамка вдоль нижней части моих камер.

Для меня это больше похоже на взлом, но это работает.

Мой единственный выбор - полностью устранить границу. Я все еще решаю, пойду ли я с этим.

0
Scott

позвольте сделать как мой код:

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

enter image description here

используйте раскадровку, чтобы изменить вкладку "Разделитель". Пользовательский "0" и "0", если вы хотите скрыть разделитель "Нет", см. изображение выше

0
Phani Sai

Просто переопределите "cellForRowAtIndexPath" и установите "cell.preservedSuperviewLayoutMargins = false" и "cell.separatorInset = UIEdgeInsets.zero" и "cell.layoutMargins = UIEdgeInsets.zero"

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let cell: LayoutTableViewCell! = tableView.dequeueReusableCell(withIdentifier: "LayoutCell") as? LayoutTableViewCell



    let currentLayout = OrderLayouts()[indexPath.row]

    cell.NameLabel?.text = currentLayout.name
    cell.DescrLabel?.text = currentLayout.descr

    if(GlobalVariables.debug){

        cell.DescrLabel?.text = "\(currentLayout.id) \n \(currentLayout.descr)"

    }

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


    return cell

}
0
MDalprato

Для меня никто не работал, кроме этого обходного пути (Swift 3.):

extension UIColor {
    static func colorWith(hex:String, alpha: CGFloat) -> UIColor {
        var cString = hex.trimmingCharacters(in: .whitespacesAndNewlines).uppercased()

        if cString.hasPrefix("#") {
            cString.remove(at: cString.startIndex)
        }

        if cString.characters.count != 6 {
            return UIColor.gray
        }

        var rgbValue:UInt32 = 0
        Scanner(string: cString).scanHexInt32(&rgbValue)

        return UIColor(red:   CGFloat((rgbValue & 0xFF0000) >> 16) / 255.0,
                       green: CGFloat((rgbValue & 0x00FF00) >> 8)  / 255.0,
                       blue:  CGFloat( rgbValue & 0x0000FF)        / 255.0,
                       alpha: alpha)
    }
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: cellReuseIdendifier, for: indexPath)

    cell.backgroundColor = UIColor.colorWith(hex: "c8c7cc", alpha: 1) // same color of line separator

    return cell
}
0
Daniele Ceglia

после ответа от @cdstamper, лучшее место - layoutSubviews UITableViewCell, в файле вашей ячейки (я установил интервал в 1%, вы можете установить в ноль), так что вам нужно только установить здесь код для обработки всех ситуаций (поворот и другие):

 -(void)layoutSubviews
    {
        [super layoutSubviews];
        if ([self respondsToSelector:@selector(setSeparatorInset:)]) {
            [self setSeparatorInset:UIEdgeInsetsMake(0,self.bounds.size.width*0.01,0,self.bounds.size.width*0.01)];
        }
        if ([self respondsToSelector:@selector(setLayoutMargins:)]) {
            [self setLayoutMargins:UIEdgeInsetsMake(0,self.bounds.size.width*0.01,0,self.bounds.size.width*0.01)];
        }
    }
0
BollMose

В Swift вы можете использовать это

    cell.selectionStyle = UITableViewCellSelectionStyle.None
    cell.preservesSuperviewLayoutMargins = false
    cell.separatorInset = UIEdgeInsetsZero
    cell.layoutMargins = UIEdgeInsetsZero
0
Anny

Я просмотрел все эти замечательные ответы и понял, что большинство из них не работают с iOS 8 или работают, но разделитель меняет размер во время анимации, вызывая нежелательное мигание. Это то, что я сделал в своем делегате приложения перед созданием окна:

[[UITableView appearance] setSeparatorInset:UIEdgeInsetsZero];
[[UITableViewCell appearance] setSeparatorInset:UIEdgeInsetsZero];

if ([UITableView instancesRespondToSelector:@selector(setLayoutMargins:)]) {
    [[UITableView appearance] setLayoutMargins:UIEdgeInsetsZero];
    [[UITableViewCell appearance] setLayoutMargins:UIEdgeInsetsZero];
    [[UITableViewCell appearance] setPreservesSuperviewLayoutMargins:NO];
}

И это то, что я добавил в свой UITableViewController:

-(void)viewDidLayoutSubviews
{
    [super viewDidLayoutSubviews];

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

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

Мне не нужно было добавлять что-нибудь еще. Спасибо всем, кто предоставил важные биты.

0
spstanley

просто поместите эти две строки в метод cellForRowAtIndexPath

  • если вы хотите, чтобы все разделительные линии начинались с нуля [cell setSeparatorInset: UIEdgeInsetsZero]; [cell setLayoutMargins: UIEdgeInsetsZero];

если вы хотите, чтобы Конкретная разделительная линия начиналась с нуля, предположим, что последняя строка начинается с нуля

if (indexPath.row == array.count-1) 
{
   [cell setSeparatorInset:UIEdgeInsetsZero];
   [cell setLayoutMargins:UIEdgeInsetsZero];
}
else
   tblView.separatorInset=UIEdgeInsetsMake(0, 10, 0, 0);
0
Shabnam

iOS 8 и позже. Swift 2.0 и более поздние версии:

override func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
    cell.separatorInset = UIEdgeInsetsZero
    if #available(iOS 8.0, *) {
        cell.layoutMargins = UIEdgeInsetsZero
    } else {
        // Fallback on earlier versions
    }
}
0
Zia