Странное поведение разделителя UITableView

У меня есть обычная таблица стиля с несколькими разделами.

Признаки: при первой загрузке таблицы каждая ячейка имеет свой разделитель как обычно, за исключением последней ячейки в каждом разделе (то есть "до" заголовка). Однако при прокрутке на некоторых ячейках появляется разделитель. Кроме того, если ячейка выбрана, затем отменит выбор, появится разделитель.

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

<_UITableViewCellSeparatorView: 0x145b1990; 
    frame = (0 47.5; 320 0.5); 
    hidden = YES; 
    layer = <CALayer: 0x145b2950>>

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

Первое предположение заключалось в том, что я делал что-то неправильно; но это происходит и с большинством базовых приложений Hello World:

- (void)viewDidLoad {
    [super viewDidLoad];
    [self.tableView reloadData];
}

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 4;
}

- (NSInteger)tableView:(UITableView *)tableView 
    numberOfRowsInSection:(NSInteger)section {
    return 2;
}

- (NSString *)tableView:(UITableView *)tableView 
    titleForHeaderInSection:(NSInteger)section {
    return @"test";
}

- (UITableViewCell *)tableView:(UITableView *)tableView 
    cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    NSString *reuseIdentifier = @"TestCell";
    UITableViewCell *cell = [tableView 
        dequeueReusableCellWithIdentifier:reuseIdentifier];
    return cell;
}

Экраны (слева: после запуска, справа: после выбора ячейки):

startafter selecting a cell

Является ли это ошибкой на стороне Apple, или я что-то упускаю? Кроме того, например, в приложении IOS Contacts разделитель никогда не скрывается над заголовком раздела...

** Обновление: **

Было возможно воспроизвести это на складе. Музыкальное приложение: например. Вкладка "Песни", без шпионажа. Выберите затем снимите флажок с первой ячейки любого раздела; появляется разделитель.

Дополнительная информация: iOS 7.1

Ответы

Ответ 1

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

Скрытие встроенного разделителя:

[self.tableView setSeparatorStyle:UITableViewCellSeparatorStyleNone];

Отображение пользовательского разделителя:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    NSString *reuseIdentifier = @"TestCell";
    XXYourCustomCell *cell = [tableView dequeueReusableCellWithIdentifier:reuseIdentifier];
    cell.customSeparatorView.hidden = (indexPath.row == ([self numberOfRowsInSection:indexPath.section] - 1));
    return cell;
}

Ответ 2

В моем случае это был Clip To Bounds в пользовательском UITableViewCell. Случайно отменил его от раскадровки. Затем снова установите для параметра Clip To Bounds в true эту проблему.

введите описание изображения здесь

Ответ 3

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

Скрыть разделитель ячейки таблицы tableView как:

    [self.tableView setSeparatorStyle:UITableViewCellSeparatorStyleNone];

Добавить пользовательский вид в пользовательскую ячейку как:

CustomCell.h
@property (nonatomic,strong) UIView* cellSeperatorView;

CustomCell.m
@synthesize cellSeperatorView;


-(UIView *)cellSeperatorView{
      if (!cellSeperatorView) {
          self.cellSeperatorView = [[UIView alloc]    initWithFrame:CGRectZero];
        [self.cellSeperatorView setBackgroundColor:[UIColor lightGrayColor]];
         [self addSubview:self.cellSeperatorView];
      }
      return cellSeperatorView;
 }

-(void)prepareForReuse{

     self.cellSeperatorView = nil;

 }

-(void)layoutSubviews{
    [super layoutSubviews];
    [self.cellSeperatorView setFrame:CGRectMake(0, 100, self.width, 1)];
}

Ответ 4

У меня была эта проблема в несколько иной ситуации, хотя мои ячейки находятся в режиме редактирования, но это не имеет значения. В моем случае я не хотел, чтобы нижний _UITableViewCellSeparatorView показывал после выбора ячейки, поэтому, просмотрев подзоны ячейки NSLog(@"%@", [cell.subviews[0] subviews]);, я увидел

(
    "<_UITableViewCellSeparatorView: 0x9df7f30; frame = (0 99; 280 1); layer = <CALayer: 0x9dfb800>>",
    "<UITableViewCellContentView: 0x9d65950; frame = (38 0; 242 99.5); opaque = NO; gestureRecognizers = <NSArray: 0x9d2e0d0>; layer = <CALayer: 0x9de8290>>",
    "<_UITableViewCellSeparatorView: 0x9dfab90; frame = (0 99.5; 280 0.5); layer = <CALayer: 0x9dfb7d0>>",
    "<UITableViewCellEditControl: 0x9df3f60; frame = (0 0; 47 100); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x9d91370>>",
    "<UIView: 0x9df4470; frame = (0 98; 280 3); layer = <CALayer: 0x9df44d0>>",
    "<UIView: 0x9d35f10; frame = (0 98; 280 3); layer = <CALayer: 0x9d39e20>>"
)

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

[[[cell.subviews[0] subviews] objectAtIndex:2] setBackgroundColor:[UIColor clearColor]];

По какой-то причине у меня нет проблемы с представлением верхнего разделителя, скорее всего из-за того, что мой заголовок в каждом разделе имеет темный цвет фона, который скрывает представление разделителя, но если вы хотите их скрыть, возможно, вы можете добавить это код

[[[cell.subviews[0] subviews] firstObject] setBackgroundColor:[UIColor clearColor]];

Обратите внимание, что я помещаю этот код в свой делегат didHighlightRowAtIndexPath. Кроме того, для моих ячеек selectionStyle установлено значение по умолчанию. Надеюсь, это поможет кому-то там!