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

UICollectionView - didDeselectItemAtIndexPath не вызывается, если выбрана ячейка

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

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
    UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"Cell" forIndexPath:indexPath];
    cell.selected = YES;
    return cell;
}

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

- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
    NSLog(@"%s", __PRETTY_FUNCTION__);
}

- (void)collectionView:(UICollectionView *)collectionView didDeselectItemAtIndexPath:(NSIndexPath *)indexPath {
    NSLog(@"%s", __PRETTY_FUNCTION__);
}

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

Однако этот делегат вызывается:

- (BOOL)collectionView:(UICollectionView *)collectionView shouldHighlightItemAtIndexPath:(NSIndexPath *)indexPath {
    NSLog(@"%s", __PRETTY_FUNCTION__);
    return YES;
}

Если я удалю cell.selected = YES, чем все работает. Есть ли кто-нибудь, кто может мне объяснить это поведение?

4b9b3361

Ответ 1

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

[collectionView selectItemAtIndexPath:indexPath animated:NO scrollPosition:UICollectionViewScrollPositionNone]; 

Полный код:

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
    UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"Cell" forIndexPath:indexPath];
    cell.selected = YES;
    [collectionView selectItemAtIndexPath:indexPath animated:NO scrollPosition:UICollectionViewScrollPositionNone];
    return cell;
}

Я держу вопрос, чтобы помочь кому-то, кто может столкнуться с той же проблемой.

Ответ 2

Я думаю, что решение @zeiteisen - это решение. Реальная вещь заключается в режиме выбора. В свойстве cell.selected нет ничего, что можно было бы установить.

Существует два свойства имени UICollectionView allowsMultipleSelection и allowsSelection.

allowsMultipleSelection по умолчанию NO, а allowsSelection - YES.

Если вы хотите выбрать только одну ячейку, тогда инициализация кода @the выглядит как

yourCollectionView.allowsMultipleSelection = NO;
yourCollectionView.allowsSelection = YES; //this is set by default

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

Если вы хотите выбрать несколько ячеек, тогда инициализация кода @будет выглядеть следующим образом:

yourCollectionView.allowsMultipleSelection = YES;
yourCollectionView.allowsSelection = YES; //this is set by default

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

0 <= number_selected_cell <= total_number_of_cell

Это политика выбора нескольких ячеек.

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

Ответ 3

У меня была такая же проблема. Я предварительно выбрал ячейки при загрузке таблицы, но мне пришлось дважды коснуться ячейки, чтобы отменить выбор. Ответ @zeiteisen помог мне. Тем не менее, я работаю в Swift 3, поэтому я решил дать ответ в Swift.

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as! Cell

    if /*Test for Selection*/ {
        cell.isSelected = true
        collectionView.selectItem(at: indexPath, animated: false, scrollPosition: .left)
    }        
    return cell
}

Ответ 4

Добавьте эту строку в свой метод didSelectItemAtIndexPath

[collectionView selectItemAtIndexPath:indexPath animated:NO scrollPosition:nil]

Ответ 5

Перезагрузка ячейки была для меня решением. Мне понадобилось мгновенное изменение изображения в ячейке. Я назначаю изображение imageView в cellForItemAtIndexPath, и когда пользователь прикасается к ячейке, я меняю изображение и запускаю mycode, а затем перезаряжаю ячейку.

 func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
        let cell = collectionView.cellForItemAtIndexPath(indexPath) as! MenuCollectionViewCell
        cell.backgroundImageView.image = UIImage(named: "selected")
        // handle tap events
        collectionView.reloadItemsAtIndexPaths([indexPath])
    }

Надеюсь, что это поможет кому-то.