Подтвердить что ты не робот

Линия разделителя UITableView исчезает при выборе ячеек в iOS7

В моем таблицеView я устанавливаю разделительную линию между ячейками. Я разрешаю выбор нескольких ячеек. Здесь мой код для настройки выбранного цвета фона ячейки:

UIView *cellBackgroundColorView = [[UIView alloc] initWithFrame:cell.frame];
[cellBackgroundColorView setBackgroundColor:[UIColor darkGray]];
[cell setSelectedBackgroundView:cellBackgroundColorView];

Проблема заключается в том, что если выбраны две соседние ячейки, между ними нет iOS7 разделительной линии, тогда как в iOS6 есть (как и ожидалось).

Я даже попробовал установить высоту фрейма cellBackgroundColorView на высоту cell.frame - 1.0, но это тоже не работает.

Любые идеи?

4b9b3361

Ответ 1

Я еще не получил его до конца (на первый взгляд это похоже на ошибку iOS 7..), но я нашел обходное решение. В tableView: didSelectRowAtIndexPath, если вы отправляете оба сообщения ниже, проблема визуально разрешена (с вероятной стоимостью исполнения).

[tableView deselectRowAtIndexPath:indexPath animated:YES];
[tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];

Для этого (для меня) deselectRowAtIndexPath: анимированный: должен содержать анимированный: ДА. Анимация, используемая для reloadRowsAtIndexPaths: withRowAnimation: не имеет значения.

Ответ 2

Добавьте этот код в ячейку для строки по indexpath

cell.selectionStyle = UITableViewCellSelectionStyleNone;
cell.textLabel.backgroundColor = [UIColor clearColor];

Ответ 3

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

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

[tableView beginUpdates];
[tableView deselectRowAtIndexPath:indexPath animated:NO]; 
//if you are doing any animation you have deselect the row here inside. 
[tableView endUpdates];
} 

Ответ 4

@samvermette answer решил проблему для меня, но мне сначала нужно было отменить выбор выбранного Row.

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath  {

    //Deselect Row
    [self.tableView deselectRowAtIndexPath:indexPath animated:YES];

    // fix for separators bug in iOS 7
    self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
    self.tableView.separatorStyle = UITableViewCellSeparatorStyleSingleLine; }

Ответ 5

Это все еще кажется проблемой с iOS 7.0.3, но я работал с ней с помощью неисчерпаемых средств подделки разделителя.

Сначала установите стиль разделителя UITableView на UITableViewCellSeparatorStyleNone. Затем вы можете использовать пользовательский подкласс UITableViewCell для подделки разделителя между ячейками для выбранных и невыбранных состояний:

@implementation MyTableViewCellSubclass

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if (self) {

        CGRect frame = self.bounds;
        frame.origin.y = frame.size.height - 1.f;
        frame.size.height = 1.f;

        // Selected background view
        //
        UIView * separatorView = [[UIView alloc] initWithFrame:frame];
        separatorView.backgroundColor = [UIColor darkGrayColor];
        separatorView.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleTopMargin;

        UIView * selectedView = [[UIView alloc] initWithFrame:self.bounds];
        selectedView.backgroundColor = [UIColor lightGrayColor];
        [selectedView addSubview:separatorView];

        self.selectedBackgroundView = selectedView;

        // Add separator view to content view for unselected state
        //
        UIView * separatorView2 = [[UIView alloc] initWithFrame:frame];
        separatorView2.backgroundColor = [UIColor darkGrayColor];
        separatorView2.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleTopMargin;

        [self.contentView addSubview:separatorView2];


    }
    return self;
}


@end

Ответ 6

Этот простой вызов сделал это для меня на iOS 8.

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    // ....
    [tableView deselectRowAtIndexPath:indexPath animated:YES]

    // ....
}

Ответ 7

Это произойдет, если вы разрешите iOS применять свой собственный стиль ячейки по умолчанию. Лучшая работа, которую я нашел до сих пор, заключается в переопределении выбранной реализации свойства:

в реализации вашего подкласса ячейки:

    @synthesize selected = _selected;

в методе инициализации:

    // problem actually is caused when you set following 
    // to UITableViewCellSelectionStyleDefault, so:

    [self setSelectionStyle:UITableViewCellSelectionStyleNone]; 

методы переопределения:

    - (BOOL)selected 
    {
        return _selected;
    }
    - (void)setSelected:(BOOL)selected animated:(BOOL)animated 
    {
        _selected = selected
        if (selected) {

            // apply your own selected style

        }
        else {

            // apply your own deselected style

        }
    }

Ответ 8

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

    NSIndexPath *indexPathOfCellAbove = [NSIndexPath indexPathForRow:(indexPath.row - 1) inSection:indexPath.section];

    if (indexPath.row > 0)
        [self.tableView reloadRowsAtIndexPaths:@[indexPathOfCellAbove, indexPath] withRowAnimation:UITableViewRowAnimationNone];
    else
        [self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];

Ответ 9

- cellForRowAtIndexPath

Create two separator views (sv1, sv2)

[cell addsubview:sv1];
[cell.selectedBackgroundView addsubview:sv2];

- didSelectRowAtIndexPath

[tableView deselectRowAtIndexPath:indexPath animated:NO];

Ответ 10

Для меня это произошло, когда я программно установил:

cell.selectionStyle = UITableViewCellSelectionStyleNone;

Когда я устанавливаю это свойство в раскадровке, он отлично работает.

Ответ 11

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

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell: UITableViewCell!
    if tableView == self.jobLevelTableView {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cellIdentifier", for: indexPath) as! CheckboxCell

        // for testing purposes
        let checked = true

        // I used M13Checkbox here, in case anybody was wondering
        cell.checkbox.setCheckState(checked ? .checked : .unchecked, animated: false) 

        if checked {
            tableView.selectRow(at: indexPath, animated: true, scrollPosition: .none)
        }

        // CULPRIT
        cell.selectionStyle = .none
        return cell
    }

    cell = UITableViewCell()
    return cell
}

Когда я установил стиль выделения на раскадровке (и удалив эквивалент кода), проблема исчезла!

Раскадровка полезна

Ответ 12

Вы также можете попробовать установить разделительные вставки на 0. Я сделал это, и он решил проблему, но компромисс - это то, что вы теряете приятный вид вставкой.

Ответ 13

Эта проблема существует и для выделения одной ячейки.

Еще одно решение - перезагрузить представление таблицы, выбрать, а затем отменить выбор:

self.selectedIndex = inIndexPath.row;
[inTableView reloadData];
[inTableView selectRowAtIndexPath:inIndexPath animated:NO scrollPosition:UITableViewScrollPositionNone];
[inTableView deselectRowAtIndexPath:inIndexPath animated:YES];

Это избавляет от тонкого графического сбоя выбора, который я видел в решении Mark.

Ответ 14

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

- (void) tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
    {
        [cell setBackgroundColor:[UIColor grayColor]];
    }

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

Ответ 15

используйте это:

- (BOOL)tableView:(UITableView *)tableView shouldHighlightRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = (UITableViewCell *)[tableView cellForRowAtIndexPath:indexPath];
    UIView *selectionColor = [[UIView alloc] init];
    selectionColor.backgroundColor = [UIColor clearColor];
    cell.selectedBackgroundView = selectionColor;
    //71
    UIView* separatorLineView = [[UIView alloc] initWithFrame:CGRectMake(0, 71, 320, 2)];/// change size as you need, where - 71 - y coordinate, 320 - weight, 2 - height
  //  separatorLineView.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"divider_goriz.png"]];// you can also put image here
    separatorLineView.backgroundColor = [UIColor redColor];
    [cell.selectedBackgroundView addSubview:separatorLineView];
    return YES;
}

Ответ 16

Я сделал это:

  • Добавить новое представление в представлении содержимого ячейки.
  • Подключить это из ячейки как selectedBackgroundView.
  • Добавить подзаголовок нового выбранного фонового представления. Установите его, чтобы начать 16px слева и покрыть остальную ширину, быть 1px высотой, 1px вниз сверху и иметь цвет фона 90% белого.

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

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

Для меня это полностью разрешило проблему (хотя я согласен, что это действительно похоже на ошибку в ios 7).

Ответ 17

Решения здесь мне не помогли. В большинстве случаев было предложено удалить выделение, но я хотел, чтобы ячейки сохраняли выбранное состояние. Поэтому идея состоит в том, чтобы отключить линию разделителя по умолчанию и использовать вашу собственную разделительную линию. Я пробовал это, но у меня были проблемы с этим (вы можете прочитать об этом здесь). Основная проблема заключалась в рисовании линии в области accessorView. Он работал только на iOS 8, но мне также понадобилось решение для iOS 7.

Мои требования:

  • Выбор должен сохраняться
  • Линия не должна исчезать (особенно в случае выбора ячейки)
  • Линия разделителя выше выбранной ячейки также не должна исчезать

Особенно третья проблема возникла из-за проблем, поскольку iOS использует какой-то эффект сглаживания для перехода на UITableViewCell к следующему. Как я узнал, это происходит только на iPad. Он имеет размер около одной точки в каждом направлении (текущая выбранная ячейка, ячейка выше), так что линия на ячейке исчезает, даже если она нарисована на самой ячейке (а не на той, которая была использована по умолчанию). Не имеет значения, находится ли эта линия на ячейке выше или на выбранной ячейке. Этот спецэффект скрывает мои строки.

решение выглядит следующим образом:

  • Используйте backgroundView, где вы рисуете две строки: один сверху (+1 точка в направлении y для iPad и 0 точек в направлении y для iPhone) и один внизу. Таким образом, он никогда не покрывается эффектом выбора.
  • Созданный фоновый вид должен использоваться только для выбранного состояния (cell.selectedBackgroundView = selectedBackground). Линия разделителя по умолчанию включена для других ячеек.

У меня есть рабочий пример с кодом С#, размещенным здесь, хотя вам нужно адаптировать его к вашим потребностям. Теперь мои проблемы выбора пропали!

Ответ 18

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

@interface MyCustomTableViewCell(){
   UIView *customSeparatorView;
   CGFloat separatorHight;
}
@property (nonatomic,weak)UIView *originSeparatorView;
@end

-(void)setSeparatorWithInset:(UIEdgeInsets)insets{

if (customSeparatorView) {
    customSeparatorView.frame = CGRectMake(insets.left, insets.top,self.width - insets.left - insets.right, self.originSeparatorView.height-insets.bottom - insets.top);
    self.originSeparatorView.hidden = YES;
    self.originSeparatorView.alpha = 0;
}else{
    for (int i = ([self.contentView.superview.subviews count] - 1); i >= 0; i--) {
        UIView *subView = self.contentView.superview.subviews[i];
        if ([NSStringFromClass(subView.class) hasSuffix:@"SeparatorView"]) {
            self.originSeparatorView = subView;
            subView.hidden = YES;
            subView.alpha = 0;
            subView.frame = CGRectMake(insets.left, insets.top,self.width - insets.left - insets.right, subView.height-insets.bottom - insets.top);

            customSeparatorView = [[subView superview] viewWithTag:separatorViewTag];
            if (!customSeparatorView) {
                customSeparatorView = [[UIView alloc] initWithFrame:subView.frame];

                customSeparatorView.tag = separatorViewTag;
                [[subView superview] addSubview:customSeparatorView];
                customSeparatorView.backgroundColor = [subView backgroundColor];
            }
            [[subView superview] bringSubviewToFront:customSeparatorView];
            break;
        }
    }
  }
}


-(void)setSeparatorColorWithColor:(UIColor *)sepColor{
if (customSeparatorView) {
    customSeparatorView.backgroundColor = sepColor;

    self.originSeparatorView.hidden = YES;
    self.originSeparatorView.alpha = 0;
}else {
    for (int i = ([self.contentView.superview.subviews count] - 1); i >= 0; i--) {
        UIView *subView = self.contentView.superview.subviews[i];
        if ([NSStringFromClass(subView.class) hasSuffix:@"SeparatorView"]) {
           self.originSeparatorView = subView;

            if (sepColor) {
                subView.hidden = YES;
                subView.alpha = 0;
                subView.backgroundColor = sepColor;

                customSeparatorView = [[subView superview] viewWithTag:separatorViewTag];
                if (!customSeparatorView) {
                    customSeparatorView = [[UIView alloc] initWithFrame:subView.frame];

                    customSeparatorView.tag = separatorViewTag;
                    [[subView superview] addSubview:customSeparatorView];
                    customSeparatorView.backgroundColor = [subView backgroundColor];
                }
                [[subView superview] bringSubviewToFront:customSeparatorView];
            }
            break;
        }
    }
  }
}

 -(void)layoutSubviews{
    [super layoutSubviews];
    [self setSeparatorWithInset:UIEdgeInsetsMake(0, 0, 0, 0)];
    [self setSeparatorColorWithColor:[UIColor colorWithRed:31/255.0 green:32/255.0f blue:35/255.0 alpha:0.2]];
 }

Ответ 19

что решило проблему для меня, была перезагрузка данных после beginUpdates и endUpdates:

    private func animateCellHeighChangeForTableView(tableView: UITableView, withDuration duration: Double) {
        UIView.animateWithDuration(duration) { () -> Void in
           tableView.beginUpdates();
           tableView.endUpdates();
           tableView.reloadData();
        }
    }

Ответ 20

Пройдет его в вашем классе UITableViewCell.

override func layoutSubviews() {
    super.layoutSubviews()

    subviews.forEach { (view) in
        if type(of: view).description() == "_UITableViewCellSeparatorView" {
            view.alpha = 1.0
        }
    }
}

Ответ 21

Мне понадобилось следующее:

"Когда пользователь выбирает строку, цвет фона выбора прозрачный/белый/независимо от того, что вы можете назвать, а разделительные линии не исчезают"

Я также нашел решение для решения следующей проблемы:

"Когда я выбираю строку в таблице (таблица обычного типа), у меня был выбор цвет серый, и если я установил cell.selectionStyle в none → Separators между клетками исчезло."

XCode - версия 9.2

Найдено следующее решение:

  • в 'tableView (.... cellForRowAT...)' let colorView = UIView(frame: CGRect(x: 0.0, y: 3.0, width: cell.frame.width, height: cell.frame.height - 1.0)) colorView.backgroundColor = UIColor.white UITableViewCellClass.appearance().selectedBackgroundView = colorView

UITableViewCellClass - ваш прототип класса ячейки он позволяет изменить цвет выделения на белый

  1. в 'tableView (... didSelectRowAt)' cell.selectionStyle = .none

  2. в UITableViewCellClass (класс ячеек прототипа)

    переопределить func layoutSubviews() {   super.layoutSubviews()

    subviews.forEach { (view) in
        if type(of: view).description() == "_UITableViewCellSeparatorView" {
            view.alpha = 1.0
        }
    }
    

    }

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

Ответ 22

Для тех из вас, кто ищет решение в Swift, это фиксировало проблему для меня. В вашем методе cellForRowAtIndexPath после вызова dequeueReusableCellWithIdentifier вам просто нужно установить ячейки selectionStyle на .None

Здесь код:

    override func tableView(tableView: UITableView?,  cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell:TextTableViewCell = tableView!.dequeueReusableCellWithIdentifier("textCell", forIndexPath: indexPath) as! TextTableViewCell

    cell.selectionStyle = .None //  This fixes the disappearing border line issue