1 пиксельный зазор между первой и второй ячейками в сгруппированном UITableView - программирование
Подтвердить что ты не робот

1 пиксельный зазор между первой и второй ячейками в сгруппированном UITableView

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

Я делаю UITableView с помощью UITableViewStyleGrouped, и я вижу небольшую (1 пиксель) белую линию между первой и второй строками каждого раздела моего представления таблицы (см. изображение)

example of gap

Кажется, что причина этой строки в том, что первая ячейка в каждом разделе на 1 пиксель выше других. Когда я устанавливаю начальную ячейку каждой группы в 29 пикселей (остальные 30), пробел исчезает, и все хорошо.

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

FYI:

  • Я убедился, что это не проблема с фоновыми изображениями, которые у меня есть - все они высотой 30 пикселей, и я заменил верхнее изображение средним изображением с тем же результатом.
  • Я удалил все границы между ячейками, установив separatorStyle = UITableViewCellSeparatorStyleNone
  • Этот эффект не происходит в UITableViewStylePlain

Любая помощь очень ценится.

Спасибо

Код для настройки таблицы:

  myTable = [[UITableView alloc] initWithFrame:CGRectMake(TABLE_SHIFT_OFFSET,
                                                          DATE_SLIDER_HEIGHT - DATE_SLIDER_SHADOW_HEIGHT,
                                                          326,
                                                          self.view.frame.size.height - DATE_SLIDER_HEIGHT + DATE_SLIDER_SHADOW_HEIGHT) style:UITableViewStyleGrouped];
  myTable.backgroundColor = [UIColor clearColor];
  myTable.backgroundView = nil;
  myTable.separatorStyle = UITableViewCellSeparatorStyleNone;
  [self.view addSubview:myTable];
  myTable.dataSource = self;
  myTable.delegate = self;

Код для настройки ячейки:

- (float)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
  // This is a hack to make sure that a white line doesnt appear between the
  // first and second rows in the table, which happens for reasons I dont understand
  if (indexPath.row == 0) {
    return 29;
  }

  return 30;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{     
  MyTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"satCell"];
  if (!cell)
  {
    cell = [[MyTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"satCell"];
  }

  cell.backgroundView = nil;
  cell.backgroundView = [[UIView alloc] initWithFrame:CGRectZero];

  cell.backgroundColor = [UIColor whiteColor];
  int numberOfRowsInThisSection = [self tableView:tableView numberOfRowsInSection:indexPath.section];

  if (numberOfRowsInThisSection == 1)
  {
    cell.backingImage = self.singleWhite;
  }
  else if (indexPath.row == 0)
  {
    cell.backingImage = self.topWhite;
  }
  else if (indexPath.row % 2 == 0)
  {
    // Even row
    if (indexPath.row == numberOfRowsInThisSection - 1)
    {
      // Last row (even)
      cell.backingImage = self.botWhite;
    }
    else
    {
      // Normal row (even)
      cell.backingImage = self.midWhite;
    }
  }
  else if (indexPath.row % 2 == 1)
  {
    // Odd row
    if (indexPath.row == numberOfRowsInThisSection - 1)
    {
      // Last row (even)
      cell.backingImage = self.botDark;
    }
    else
    {
      // Normal row (odd)
      cell.backingImage = self.midDark;
    }
  }

  // Setup cell text [REMOVED FOR BREVITY]

  return cell;
}

Код для настройки обратного изображения в MyTableViewCell:

- (void)setBackingImage:(UIImage *)backingImage
{
  if (self.backingImage != backingImage)
  {
    _backingImage = nil;
    _backingImage = backingImage;
    self.backingView.image = backingImage;
  }
}

self.backingView настроен с использованием следующего кода:

[[UIImageView alloc] initWithFrame:CGRectMake(7, 0, 307, 30)];
4b9b3361

Ответ 1

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

Проще говоря, верхняя и нижняя ячейки используют одну дополнительную точку, но разделитель скрывает ее, поэтому решение:

  • Выделите дополнительный интервал (как вы уже сделали)
  • Сделайте фоном повторяющийся шаблон или растягиваемое изображение (не пытайтесь продвигать себя, но ответ, который я дал в предыдущей связанной теме, также объясняет, как сделать растягиваемое изображения).
  • Не скрывайте разделитель, но совпадение - это цвет с фоном ячеек, поэтому он выглядит как скрытый.

Вариант 2 кажется "самым чистым" и добавляет преимущество поддержки переменных высот ячеек таблицы.

И почему у этого есть дополнительная точка? Только Apple знает.

Ответ 2

По моему опыту, сгруппированные представления таблиц добавляют 1 пункт (не пиксель!) к высоте первой и последней строки в каждом разделе. Вы должны уметь это видеть, добавляя код отладки, чтобы переопределить layoutSubviews в классе ячейки таблицы, попросите его вызвать super и затем напечатать файл bounds.size.height.

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

[Изменить] Это хороший бит кода отладки для проверки иерархии представлений. (Вы не можете вызвать recursiveDescription напрямую, потому что он является приватным, и ваш код не будет компилироваться по умолчанию по настройкам Xcode.)

NSLog(@"%@", [self.view performSelector:@selector(recursiveDescription)]);

Ответ 3

Если вы выполните следующее, это устранит вашу проблему: Избавьтесь от "backingImage" (backingView). Вместо использования свойства cell backgroundView просто присвойте ему UIImageView. Теперь, когда вы создаете свой UIImageView для фона, убедитесь, что вы растягиваете UIImage следующим образом:

UIImage *bg = [UIImage imageName:@"filename.png"];
bg = [bg resizableImageWithCapInsets:UIEdgeInsetsMake(15, 0, 15, 0)];

ПРИМЕЧАНИЕ. Я предполагаю, что ваше изображение имеет высоту 30 точек. Глядя на изображение, которое вы используете, он может растягиваться вертикально, что я делаю в этом примере. Чтобы сэкономить больше памяти, вы также можете растянуть ее по горизонтали, но у вас есть возможность не поддаваться этому.

Надеюсь, это поможет!

Ответ 4

Это крики заголовков для меня. Вы переопределяете метод viewForHeaderInSection? Мое лучшее предположение заключается в том, что границы для вашей первой ячейки в каждом разделе каким-то образом выравниваются с границами для заголовка этого раздела.

Попробуйте переопределить эти методы:

– tableView:viewForHeaderInSection:
– tableView:viewForFooterInSection:
– tableView:heightForHeaderInSection:
– tableView:heightForFooterInSection:
– tableView:willDisplayHeaderView:forSection:
– tableView:willDisplayFooterView:forSection:

и играть с тем, что они возвращают. Особенно heightForHeaderInSection/viewForHeaderInSection/willDisplayHeaderView: ForSection:

Ответ 5

В iOS 8 без разделителей в сгруппированном представлении таблицы у меня тоже была проблема. Между моими разделами был разрыв в 0,5 ф. Поскольку фон за моим столом не был тем же цветом, это было очень заметно. Решение состоит в том, чтобы заполнить пустой заголовок размером 1 px, а затем вылить его на 1 пиксель с другим видом. Работает как шарм.

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
    UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, 1)];
    view.backgroundColor = [UIColor whiteColor];
    view.opaque = YES;
    view.clipsToBounds = NO;

    //Spill a view out by one pixel.
    UIView *subView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, 2)];
    subView.backgroundColor = [UIColor whiteColor];
    subView.opaque = YES;
    [view addSubview:subView];
    return view;
}

- (CGFloat)tableView:(UITableView *)tableView
heightForHeaderInSection:(NSInteger)section {
    return 1;
}