Есть ли способ заставить ячейки UITableView в iOS 7 не иметь разрыв строки в разделителе?

Я заметил, что в iOS 7 UITableViewCells имеет разрыв строки в разделителе ячейки, который не имеет iOS 6. Есть ли способ избавиться от этого перерыва? Изменение разделителя на none, а затем создание UIViews с цветом разделителя по-прежнему приводит к возникновению белого разделителя независимо.

Ответ 1

Для iOS7:

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

Для iOS8:

Сначала настройте представление таблицы следующим образом:

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

Затем в вашем методе cellForRowAtIndexPath: настройте ячейку следующим образом:

if ([cell respondsToSelector:@selector(layoutMargins)]) {
    cell.layoutMargins = UIEdgeInsetsZero;
}

Примечание. Включите как layoutMargins, так и separatorInset, чтобы поддерживать обе версии iOS

Ответ 2

Вы также можете установить " Вставка разделителя" из раскадровки:

enter image description here

enter image description here

Ответ 3

Если вы хотите поддерживать более старые версии iOS, вы должны проверить наличие этого метода перед его вызовом:

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

Ответ 4

Выяснил это.

[self.tableView setSeparatorInset:UIEdgeInsetsMake(0, 0, 0, 0)];

Ответ 5

Выбранный ответ не помог мне. Но это да и работает от ios 2.0:

   [self.tableView setSeparatorStyle:UITableViewCellSeparatorStyleNone];

Ответ 6

Быстрая версия

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

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

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

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

ПРИМЕЧАНИЕ: это правильная, менее запутанная реализация, о чем говорится в ответе Майка Абдуллы; установка сохраненных ячеекSuperviewLayoutMargins = NO гарантирует, что ваш вид таблицы не переопределит настройки ячейки.

Первый шаг - установите поля вашей ячейки:

/*
    Tells the delegate 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 seperator inset
    if cell.respondsToSelector("setSeparatorInset:") {
        cell.separatorInset = UIEdgeInsetsZero
    }

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

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

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

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

Ответ 7

Для постоянного решения для всего приложения вызовите это в приложении: doneFinishLaunching.. любое табличное представление будет "исправлено"

if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7) {
  [[UITableView appearance]setSeparatorInset:UIEdgeInsetsZero];
}

Ответ 8

И в iOS 8, на основе сообщения Seth McFarlane здесь, вам нужно начать работу с layoutMargins. Для меня это сделало следующее:

  • В ApplicationDidFinishLaunching запустите следующее:

    if ([UITableViewCell instancesRespondToSelector:@selector(setLayoutMargins:)]) {
        [[UITableViewCell appearance]setLayoutMargins:UIEdgeInsetsZero];
    }
    
  • Создайте в UITableView следующую категорию:

    @interface UITableView(WJAdditions)
    -(void) wjZeroSeparatorInset;
    @end
    
    @implementation UITableView (WJAdditions)
    -(void) wjZeroSeparatorInset {
    #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000
      if ([self respondsToSelector:@selector(setLayoutMargins:)]) {
        self.layoutMargins = UIEdgeInsetsZero;
      }
    #endif
    #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000
       if ([self respondsToSelector: @selector(setSeparatorInset:)])
          self.separatorInset = UIEdgeInsetsZero;
       }
    #endif
    }
    @end
    
  • В UITableViews, вскоре после инициализации, вызовите

    [self wjZeroSeparatorInset];
    
  • В UITableViewControllers вам нужно следующее:

    -(void) viewWillLayoutSubviews {
      [super viewWillLayoutSubviews];
      UITableView* tv = self.tableView;
      if ([tv respondsToSelector:@selector(setLayoutMargins:)]) {
        [tv setLayoutMargins:UIEdgeInsetsZero];
      }
    }
    

Ответ 9

В iOS 8 появляется небольшая ошибка. Пользовательское значение для вставки разделителя не применяется к ячейкам с текстом в нем. Я попытался установить его из конструктора интерфейса и с помощью кода, но не работал. Я также опубликовал отчет об ошибке.

enter image description here

Тем временем у меня есть небольшое обходное решение для достижения этого. Я просто рисую линию на ячейке. Создайте подкласс UITableViewCell и переопределите метод drawRect. Также не забудьте установить для свойства separator UITableView значение None. Вот код. Он в Swift, но с его в основном C, вы можете использовать то же самое и в Objective-C.

override func drawRect(rect: CGRect) {
    super.drawRect(rect)

    let context = UIGraphicsGetCurrentContext()
    CGContextSetStrokeColorWithColor(context, UITableView().separatorColor.CGColor) // seperator color
    CGContextSetLineWidth(context, 2) // separator width

    CGContextMoveToPoint(context, 0, self.bounds.size.height)
    CGContextAddLineToPoint(context, self.bounds.size.width, self.bounds.size.height)
    CGContextStrokePath(context)
}

Ответ 10

Reset separatorInset исправляет эту проблему для меня:

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

Ответ 11

Решение:

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

Ответ 12

Остерегайтесь установки разделителя. Вставка таблицыView в UIEdgeInsetsZero, похоже, одновременно нарушает левый край заголовков разделов! (по крайней мере, на iOS 7.1)

Если вы хотите отображать заголовки разделов с помощью tableView: titleForHeaderInSection: и по-прежнему получать эффект желания без разрыва строки между UITableViewCells, вы должны установить separatorInset непосредственно в ячейках вместо tableView!

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    // ...
    [cell setSeparatorInset:UIEdgeInsetsZero];

Ответ 13

Для iOS8 + это сработало для меня,

tableView.layoutMargins = UIEdgeInsetsZero

и в cellForRowAtIndexPath:

cell.layoutMargins = UIEdgeInsetsZero;

Ответ 14

- (void)viewDidLoad
{
    [self.tableView setSeparatorStyle:UITableViewCellSeparatorStyleNone];

    [super viewDidLoad];

    // Additional setup
}

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

Ответ 15

@implementation UITableView (HGApperance) 
-(void)setSeparatorXMargin:(CGFloat)margin{
    // iOS 7
    if ([self respondsToSelector:@selector(setSeparatorInset:)]) {
        [self setSeparatorInset:UIEdgeInsetsZero];
    }

    if ([self respondsToSelector:@selector(layoutMargins)]) {
        self.layoutMargins = UIEdgeInsetsZero;
    }
}
@end

Для TableviewCell, Willam answer работает идеально.

Ответ 16

В iOS8 и выше

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

Сделайте или проверьте его шаг за шагом.

1, После выделения и init UITableView установите его свойство layoutMargins.

if ([_tableView respondsToSelector:@selector(setLayoutMargins:)]) {
    _tableView.layoutMargins = UIEdgeInsetsZero ;
}

2. В методе - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath после выделения и инициализации пользовательского UITableViewCell установите его свойство layoutMargins.

if ([cell respondsToSelector:@selector(setLayoutMargins:)]) {
    cell.layoutMargins = UIEdgeInsetsZero ;
}

3. Приходит самая важная часть. Если вы переопределите метод - (void)layoutSubviews UITableViewCell, , не забудьте вызвать его супер.

- (void)layoutSubviews
{
    [super layoutSubviews] ;

    // layout the subviews
}

Ответ 17

Версия Xamarin.iOS

Я расширил разделитель UITableView на всю ширину в Xamarin.iOS на iOS 8.4 с помощью сообщений Luis E. Prado и King-Wizard. Мне нужно было установить SeparatorInset и LayoutMargins, чтобы он работал. Я не писал проверки для более низких версий iOS, так как я нацелен на iOS 8 и выше.

Я написал следующие два метода расширения С#, чтобы установить полную ширину разделителя UITableView на уровне UITableView или UITableViewCell. Вы можете использовать один или оба из этих методов в зависимости от желаемого эффекта (см. Пояснения ниже).

UITableView

Задайте свойства UITableView для изменения разделителей, которые появляются после пустых ячеек. Этот метод SetLayoutMarginsZero можно вызвать из соответствующего метода ViewController ViewDidLoad.

public static void SetLayoutMarginsZero(this UITableView tableView)
{
    tableView.SeparatorInset = UIEdgeInsets.Zero;
    tableView.LayoutMargins = UIEdgeInsets.Zero;
}

UITableViewCell

Задайте свойства UITableViewCell для изменения разделителей, которые появляются после заполнения ячеек. Этот метод SetLayoutMarginsZero можно вызвать из метода TableViewSource GetCell.

public static void SetLayoutMarginsZero(this UITableViewCell tableViewCell)
{
    tableViewCell.SeparatorInset = UIEdgeInsets.Zero;
    tableViewCell.LayoutMargins = UIEdgeInsets.Zero;
    tableViewCell.PreservesSuperviewLayoutMargins = false;
}