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

Выбранная ячейка UITableView не остается выбранной при прокрутке

У меня возникают проблемы с ядром таблицы, не сохраняющим их "выбранное" состояние при прокрутке таблицы. Вот соответствующий код:

@property (nonatomic, strong) NSIndexPath *selectedIndexPath;

-(void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    self.selectedIndexPath = indexPath;
    //do other stuff
}

-(UITableViewCell*) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    MyCustomCell_iPhone* cell = [tableView dequeueReusableCellWithIdentifier:@"MyCustomCell_iPhone"];

    if (cell == nil)
        cell = [[[NSBundle mainBundle] loadNibNamed:@"MyCustomCell_iPhone" owner:self options:nil] objectAtIndex:0];

    if ([indexPath compare: self.selectedIndexPath] == NSOrderedSame) {
        [cell setSelected:YES animated:NO];
    }

    return cell;
}

И для ячейки:

- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
    [super setSelected:selected animated:animated];

    if (selected) {
        self.selectedBg.hidden = NO;
    }else{
        self.selectedBg.hidden = YES;
    }
}

- (void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated
{
    [super setHighlighted:highlighted animated:animated];

    if (highlighted) {
        self.selectedBg.hidden = NO;
    }else{
        self.selectedBg.hidden = YES;
    }
}

Как я могу выделить выделенную ячейку для выделения? Если я прокручиваю его с экрана, когда он прокручивается назад на экране, он появляется в своем невыбранном состоянии (с его выделенным блоком Bg).

EDIT: Удаление метода setHighlighted из ячейки устраняет проблему. Однако это означает, что я не выделяю состояние при нажатии на ячейку таблицы. Я хотел бы знать решение этого.

4b9b3361

Ответ 1

Если бы та же проблема, выбранный элемент аксессуар cell исчез в списке прокрутки. Мой сотрудник нашел довольно рубить эту проблему. Причина в том, что в iOS 7 в touchhesBegan событие UITableView отменяет выбор выбранной ячейки и выбирает косвенную ячейку. В iOS 6 это не происходит, и при прокрутке выбранные ячейки остаются выбранными. Чтобы получить такое же поведение в iOS 7, попробуйте:

1) Включите множественный выбор в таблицеView.

2) Перейдите к методу делегирования tableView didSelectRowAtIndexPath и снимите выделение соты с помощью кода:

   NSArray *selectedRows = [tableView indexPathsForSelectedRows];
for(NSIndexPath *i in selectedRows)
{
    if(![i isEqual:indexPath])
    {
        [tableView deselectRowAtIndexPath:i animated:NO];
    }
}

Исправлена ​​проблема! Надеюсь, это было бы полезно, извините за мой плохой английский кстати.

Ответ 2

Я знаю, что мой метод не очень ортодоксальный, но, похоже, работает. Вот мое решение:

func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
    if cell.selected {
        cell.selected = true
    } else {
        cell.selected = false
    }
}

Вы также должны использовать все методы, упомянутые в своем сообщении (@soleil)

Ответ 3

iOS 7/8 обе снижают выделение ячейки при прокрутке (как отметил Александр Ларионов).

Более простым решением для меня было реализовать этот метод UIScrollViewDelegate в моем ViewController:

 - (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
     NSInteger    theRow       = [self currentRowIndex]; // my own method
     NSIndexPath *theIndexPath = [NSIndexPath indexPathForRow:theRow inSection:0];
     [self.myTableView selectRowAtIndexPath:theIndexPath 
                                   animated:NO 
                             scrollPosition:UITableViewScrollPositionNone];
 }

Это работает, потому что мой viewController является делегатом UITableView, а UITableView наследуется от UIScrollView.

Ответ 4

Я использую Xcode 9.0.1 и Swift 4.0. Я обнаружил, что следующие коды разрешили мою метку выбора, когда ячейки за пределами экрана и обратно:

override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
    if cell.isSelected {
        cell.accessoryType = .checkmark
    } else {
        cell.accessoryType = .none
    }
}

Ответ 5

Если вы хотите получить то же самое в Swift, то вот код. Кстати, я использую Xcode 7.2 с Swift 2.1.

override func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
    if cell.selected == true{
        cell.selected = true
        cell.backgroundColor = UIColor.blackColor()
    }else{
        cell.backgroundColor = tableViewCellColor //Don't panic its my own custom color created for the table cells.
        cell.selected = false
    }
}

Сделайте другую настройку, что хотите.

Спасибо..

Надеюсь, что это помогло.

Ответ 6

Вы пытались сравнить строки указательных путей вместо всего объекта пути индекса?

if ((indexPath.row == self.selectedIndexPath.row) && (indexPath.section == self.selectedIndexPath.section)) {
    [cell setSelected:YES animated:NO];
}

Ответ 7

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

1) Внесите -scrollViewWillBeginDragging: и -scrollViewWillEndDragging:withVelocity:targetContentOffset: и вручную выделите ячейку для выбранной строки (если она есть) во время прокрутки.

Моя выглядит так:

- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollview {
    self.scrollViewIsDragging = YES;

    if( [self.tableView indexPathForSelectedRow] ) {
        [[self.tableView cellForRowAtIndexPath:[self.tableView indexPathForSelectedRow]] setHighlighted:YES];
    }
}

- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset {
    self.scrollViewIsDragging = NO;

    if( [self.tableView indexPathForSelectedRow] ) {
        [[self.tableView cellForRowAtIndexPath:[self.tableView indexPathForSelectedRow]] setHighlighted:NO];
    }
}

Свойство scrollViewIsDragging существует так, что в -tableView:cellForRowAtIndexPath: мы можем убедиться, что все вновь выделенные ячейки имеют правильное выделение (например, если ячейка для выбранной строки прокручивается на экран после того, как она была выключена). Соответствующая часть этого метода выглядит следующим образом:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    // ... cell creation/configuration ...

    if( self.scrollViewIsDragging && [[tableView indexPathForSelectedRow] isEqual:indexPath]) {
        [cell setHighlighted:YES animated:NO];
    }

}

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

Ответ 8

UITableViewCell имеет свойство BOOL " selected". Всякий раз, когда вы загружаете ячейку, проверяйте состояние выбранного и делаете выбор или отключение соответствующим образом следующим образом в определении cellForRowAtIndexPath:

if (cell.selected) {
    // Maintain selected state
}
else{
     // Maintain deselected state
}

Ответ 9

Отправленный быстрый ответ на это здесь: fooobar.com/questions/118043/...

В нем я также объясню, почему это происходит.

Ответ 10

Решение Swift 3, 2017.

Я исправил проблему с помощью этой простой строки кода:

cell.isSelected = tableView.indexPathsForSelectedRows?.contains(indexPath) ?? false

Внутри метода tableView (tableView: cellForRowAt indexPath:):

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    // Dequeue a reusable cell
    if let cell = tableView.dequeueReusableCell(withIdentifier: "YourCellID") {

        cell.isSelected = tableView.indexPathsForSelectedRows?.contains(indexPath) ?? false

        // Now you can safely use cell.isSelected to configure the cell 

        // ...your configurations here

        return cell
    }

    return UITableViewCell()
}

Ответ 11

Swift 5

Поместите следующий код в свой пользовательский подкласс UITableViewCell:

override func setHighlighted(_ highlighted: Bool, animated: Bool) {
    guard !isSelected else { return }

    super.setHighlighted(highlighted, animated: animated)
    if highlighted {
        // Style cell for highlighted
    } else {
        // Style cell for unhighlighted
    }
}

override func setSelected(_ selected: Bool, animated: Bool) {
    super.setSelected(selected, animated: animated)
    if selected {
        // Style cell for selected
    } else {
        // Style cell for unselected
    }
}

Объяснение: Попробуйте установить точки останова как для setHighlighted и для setSelected. Вы обнаружите, что метод dequeueReusableCell вызывает setSelected затем setHighlighted в этом порядке для сброса новой ячейки. Таким образом, ваш код выделения сметает стиль, который вы сделали в своем коде выбора. Исправление без взлома состоит в том, чтобы избежать разрушения выбранного стиля при setHighlighted(false, animated: false).