iOS 8 роздільник UITableView 0, не працює


662

У мене є додаток, де для UITableViewвставки роздільника встановлено спеціальні значення - Вправо 0, Вліво 0. Це чудово працює iOS 7.x, однак уiOS 8.0 я бачу, що для вставки роздільника встановлено значення за замовчуванням 15праворуч. Незважаючи на те, що у файлах xib, які він встановив 0, він все ще відображається неправильно.

Як видалити межі UITableViewCellрозділювача?


Ви спробували встановити вкладку на 0,001 замість 0? Я пам’ятаю, мав подібну проблему, коли крайова вставка не реагувала на 0, але реагувала на 0,001 (або щось подібне мале).
прісна

Я спробував це, і це не вийшло ..
user3570727

4
Тоді я б запропонував встановити колір роздільників [UIColor clearColor]і намалювати власні роздільники. Ви набагато гнучкіші таким чином.
прісна

1
Я досі не можу повірити, що це все ще не одна з UITableViewCellSeparatorStyleтипових настройок. Навіть прийнята відповідь є дійсно брудним злом на мою думку.
Енріко Сусатіо

Відповіді:


1071

iOS 8.0 представляє властивість layoutMargins на вікнах ТА та представленнях таблиць.

Цей ресурс недоступний на iOS 7.0, тому перед його призначенням переконайтесь, що ви перевірили його!

Просте виправлення полягає в підкласифікації вашої клітини та перевласненні властивості поля макета, як запропонував @ user3570727. Однак ви втратите будь-яку поведінку системи, як-от успадковування запасів від безпечної зони, тому я не рекомендую наступне рішення:

(ObjectiveC)

-(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перекривати все 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];
    }
}

Швидкий 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];
    }
} 

Швидкий 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: Мохамед Салех звернув мою увагу на можливу зміну прошивкою 9. Ви , можливо , буде потрібно встановити Table View - х cellLayoutMarginsFollowReadableWidthдоNO , якщо ви хочете налаштувати врізки або поля. Ваш пробіг може відрізнятися, це не дуже добре зафіксовано.

Ця властивість існує лише в iOS 9, тому обов'язково перевірте її перед налаштуванням.

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

Швидкий 4:

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

(вищевказаний код із iset 8 UITableView-роздільник 0, не працює )

EDIT: Ось чистий підхід для створення інтерфейсів:

TableViewAttributesInspector TableViewCellSizeInspector

ПРИМІТКА: iOS 11 змінює та спрощує велику частину такої поведінки, буде оновлено оновлення ...


2
Для перегляду таблиць усередині UIPopoverController я повинен був робити те, як показано вище, а не просто у willDisplayCell.
Чжан

44
Я також виявив, що незважаючи на код вище, я все-таки повинен був додати пропозицію cell.preservesSuperviewLayoutMargins = NOper @ bffmike або після прокрутки способів появи вставки. (wtf ??)
inorganik

Що робити, якщо ми хочемо встановити поле лише для одного типу комірок у згрупованій таблиціView?
SAHM

Ви можете спробувати встановити його у willDisplayCell і побачити, чи справді це працює (у вас є ручка на комірці, тому це має бути тривіально). Якщо цього не відбувається, нам потрібно подати помилку. Повинна бути специфічна межа розмітки для комірок, IMO.
cdstamper

2
Це спрацювало для мене з додаванням до cell.preservesSuperviewLayoutMarginsмого методу джерела даних:- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
mts

257

Аргумент !!! Погравши або зробивши це у своєму Cellпідкласі:

- (UIEdgeInsets)layoutMargins
{
    return UIEdgeInsetsZero;
}

або встановивши cell.layoutMargins = UIEdgeInsetsZero;фіксовану для мене.


13
перше рішення у цій відповіді працювало на мене, друге - не працювало.
шпигун

5
Не використовуйте просто cell.layoutMargins = UIEdgeInsetsZero; так як вона вийде з ладу на iOS 7.x. Краще перевірити, чи існує селектор перший, перш ніж використовувати його. Дивіться моє рішення нижче.
Рікі

3
Він не встановлює cell.layoutMargins ... Це рішення чудово працює, коли у вас вже є власні комірки.
Шьорд Перфорс

11
Це буде добре працювати в iOS 7, оскільки метод не буде викликаний! Також вам потрібно встановити макет подання таблиці, Поширення, або це не працюватиме.
cdstamper

2
переопределення аксесуара працювало на мене. але всі інші рішення цього не зробили. навіть налаштування separatorInsetв IB не працювало. також є проблема з кольорами фону перегляду таблиці. це справді хворі речі.
glasz

178

Давайте миттєво розберемося з проблемою, перш ніж сліпо заряджатися, щоб спробувати її виправити.

Швидкий покол навколо налагоджувача скаже вам, що розділові лінії - це підзагляд UITableViewCell . Здається, що сама клітина бере на себе відповідальну відповідальність за компонування цих рядків.

iOS 8 представляє концепцію розміщення поля . За замовчуванням поля макета представлення є 8ptз усіх боків, і вони успадковуються від подань предків.

Як найкраще ми можемо сказати, викладаючи свою розділову лінію, UITableViewCellобирає дотримуватися лівого поля макета, використовуючи його для обмеження лівого вставки.

Збираючи все це разом, щоб досягти бажаного введення дійсно нуля, нам потрібно:

  • Встановіть лівий запас макета на 0
  • Зупиніть будь-які успадковані поля, що перевищують це

Якщо це так, досягти досить простого завдання:

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

Що слід зазначити:

  • Цей код потрібен лише запускати лише один раз на комірку (ви просто налаштовуєте властивості комірки зрештою), і нічого особливого не має, коли ви вирішите її виконати. Робіть те, що здається вам найчистішим.
  • На жаль, жодна властивість не доступна для налаштування в Interface Builder, але ви можете вказати визначений користувачем атрибут виконання, preservesSuperviewLayoutMarginsякщо потрібно.
  • Зрозуміло, що якщо ваша програма також націлена на попередні версії ОС, вам потрібно буде уникати виконання вищевказаного коду до запуску на iOS 8 і вище.
  • Замість того, щоб встановити preservesSuperviewLayoutMargins, ви можете налаштувати представлення предків (наприклад, таблицю), щоб вони також 0залишили поле, але це здається по суті більш схильним до помилок, оскільки ви не керуєте цією ієрархією.
  • Напевно, було б трохи чистіше встановити лише лівий край 0та залишити інших.
  • Якщо ви хочете мати 0 "вкладки" на "додаткових" роздільниках, які UITableViewмалюють внизу таблиць простого стилю, я здогадуюсь, що також потрібно буде вказати ті самі налаштування на рівні таблиці (не пробували цього!)

3
Дякую! Це справді більш стисла відповідь. Набагато краще, ніж перекриття двох методів і грубе примушення до цього.
LunaCodeGirl

16
В iOS 8 для мене це не спрацювало б[self.tableView setSeparatorInset:UIEdgeInsetsMake(0, 0, 0, 0)];
davetw12

1
Ви маєте мій голос, дякую за чітке пояснення. Я лише зазначу, що сам TableView також має layoutMargins, які, можливо, потрібно буде встановити на додаток до separatorInset, у деяких випадках.
cdstamper

@ davetw12 та @cdstamper Чи можете ви надати якісь докази цього? Всі мої дослідження до цих пір говорять про те, що налаштування layoutMarginsі preservesSuperviewLayoutMarginsна клітинку - це все, що потрібно. Все інше відчуває, як довіряти вуду.
Майк Абдулла

3
Ні, це не форма вуду @MikeAbdullah. Для того, щоб уникнути типового separatorInsetзначення UITableViewCelliOS 8, вам слід встановити значення UIEdgeInsetsнуля як на, так UITableViewі на UITableViewCell. Якщо ви не зробите обох, у вас залишиться лівий вклад, більший за нуль. Я це підтверджував кілька разів.
davetw12

58

Я вважаю, що це те саме питання, яке я задав тут: Видалити 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. Отже, найкращим способом було б перевірити, чи layoutMarginsіснує перший раніше setLayoutMargins:UIEdgeInsetsZero.


Як можна використовувати цей підхід, якщо мета розгортання встановлена ​​на iOS 7?
Петро

Я ставлю код для tableView в viewDidLoad і працюю чудово. Я думаю, що не потрібно їх викликати кожен раз у willDisplayCell ().
Абдулла Умер

46

Ви можете використовувати 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 додала властивість під назвою preserveSuperviewLayoutMargins до вашої клітини, яка не дозволить їй успадкувати налаштування поля Вашого перегляду таблиці. Таким чином, ваші клітини можуть налаштувати власні поля незалежно від подання таблиці. Подумайте про це як на переоцінку.

Це властивість називається preserveSuperviewLayoutMargins , а встановлення його на NO дозволяє переосмислити настройки макета таблиці ViewMargin на ваш власний елемент клітини. Це заощаджує час ( вам не потрібно змінювати налаштування таблиці ) і є більш стислим. Будь ласка, зверніться до відповіді Майка Абдулли для детального пояснення.

ПРИМІТКА: це правильна, менш брудна реалізація, що виражається у відповіді Майка Абдулли; встановлення пресервів вашої коміркиSuperviewLayoutMargins = НІ гарантує, що ваше перегляд таблиці не перекриє налаштування комірок.

Перший крок - Налаштування поля вашої комірки:

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

Якщо встановити властивість preserveSuperviewLayoutMargins у вашій комірці на 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, в моєму випадку мені потрібно було скористатися лише першим кроком цього пояснення.

Другий крок необхідний лише у тому випадку, якщо ви маєте незаселену клітинку під виведеними клітинками, тобто. якщо таблиця більша за кількість рядків у моделі таблиці. Якщо не зробити другий крок, це призведе до різного зміщення сепаратора.


1
Вам не потрібно перевіряти селектори в willDisplayCellметоді, оскільки сам метод вже є iOS 8+ і ніколи не буде викликаний зі старих версій.
Рівера

38

У Swift це трохи більше дратує, тому що layoutMarginsце властивість, тому вам доведеться перекривати геттера та сеттера.

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

Це ефективно зробить layoutMarginsчитання тільки, що в моєму випадку прекрасно.


Тільки це рішення спрацювало для мене. І мені не потрібно було додавати додатковий код рядків у методи. Я використовував власні клітини.
Раміс

2
Для статичної комірки, за винятком переважаючого layoutMargins, потрібно ще змінити стиль роздільника комірки на "Спеціальні вставки" та встановити ліве значення на "0" у розкладі.
hufeng03

22

Для iOS 9 потрібно додати:

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

Для більш детальної інформації зверніться до питання .


12
смішно додати якийсь код для кожної версії, щоб початковий вигляд залишався однаковим ...
Крістіан

20

Розширення Swift 2.0

Я просто хотів поділитися розширенням, яке я зробив, щоб видалити поля з роздільників комірок viewview.

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 замість подання таблиці, додавання нижче рядків у компоновці клітини методSubview працює для мене.

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

Просте рішення у 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

Для мене проста лінія зробила цю роботу

cell.layoutMargins = UIEdgeInsetsZero

називають це методом delegate cellForRowAtIndexPath. Гарна відповідь :)
saintjab

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

Відповідь Лукаша у Свіфті:

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

Це здається мені найчистішим (поки що), оскільки всі корективи осередку / tableView краю / поля робляться в tableView:willDisplayCell:forRowAtIndexPath:методі, не забиваючи непотрібний код tableView:cellForRowAtIndexPath:.

До речі, я встановлюю лише лівий сепаратор коміркиInset / 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)
        }
    }

Що саме для вас не працює? Щойно перевірив цей код на симуляторі iPhone 5, встановлений iOS 8.1 SDK, і все так, як було, коли я спочатку опублікував цю відповідь. Код був складений та запущений з Xcode 6.1.1.
Іван

4

Більшість відповідей показує розділові врізки і макет поля створюються над різними методами (тобто viewDidLayoutSubviews, willDisplayCellі т.д.) для клітин і 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

Використовуйте фрагмент коду нижче, щоб уникнути небажаних проблем із прокладкою для 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

Замість оновлення 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

Ви можете подумати, що а) також просто переосмислити separatorInsetрозширення, або б) layoutMarginsнатомість встановити проксі-сервер зовнішнього вигляду . Ні це не спрацює. Навіть незважаючи на те separatorInset, що вказано як властивість, спроба змінити його як властивість (або метод) створює помилки компілятора. А встановлення проксі-сервера зовнішнього вигляду для UITableViewCell's layoutMargins(або, з цього приводу, також встановлення проксі-серверів зовнішнього вигляду для UITableView' s layoutMarginsі separatorInset) не впливає.


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

Побачивши відповіді на третьому поверсі, я спробував з’ясувати, у чому полягає взаємозв’язок налаштування роздільника між TableView та TableViewCell і зробив деякий тест. Ось мої висновки:

  1. ми можемо врахувати, що встановлення роздільника комірки на нуль повинно перемістити сепаратор у два етапи: перший крок - встановити сепараторну клітинку на нуль. другий крок - встановити маржинальний розмір комірки на нуль.

  2. встановити Tableview в separatorinset і marginlayout може вплинути на клітини separatorinset . Однак, з тесту, я виявляю, що розділовий набір TableView видається марним, маржиналізація TableView насправді може впливати на маржиналізацію комірки .

  3. встановити PreserveSuperviewLayoutMargins Cell = false, може відрізати ефект маргінального розкладу TableView на клітини.

  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;
    }
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.