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

UICollectionView shouldSelectItemAtIndexPath = NO не позволяет отказаться от выбора старого выбора?

У меня есть несколько элементов в CollectionView, но только некоторые из них должны быть доступны. Я обрабатываю это методом делегата:

- (BOOL)collectionView:(UICollectionView *)collectionView shouldSelectItemAtIndexPath:(NSIndexPath *)indexPath

Моя проблема возникает, если выбран выбранный элемент, и на следующем шаге выбор не выбираемого элемента отклоняется ifSelectItemAtIndexPath, возвращающим NO, выбранный элемент все равно отменяется.

Я также пытался использовать

- (BOOL)collectionView:(UICollectionView *)collectionView shouldHighlightItemAtIndexPath:(NSIndexPath *)indexPath

Но это та же проблема.

Является ли это правильным желаемым поведением UICollectionView? И если да, как я могу избежать отмены моего последнего выбранного элемента, если выбран не выбранный элемент?

4b9b3361

Ответ 1

Я должен исправить свое предположение: Последний выбор не будет отменен!

Чтобы изменить внешний вид ячейки при выборе, я переопределил setSelected accessor из UICollectionViewCell. При выборе не выбираемого элемента, аксессуар setSelected из последней выбранной ячейки вызывается несколько раз. Сначала с состоянием NO, затем с состоянием YES и в конце с NO снова. Последнее состояние NO заставило мою ячейку установить ее внешний вид в отношении не выбранной ячейки.

Я не знаю причины этого странного поведения и не могу его решить.

Моим обходным путем является изменение внешнего вида выбранных ячеек непосредственно в ViewController.

Установите выбранный вид в:

- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath

Удалить выбранный внешний вид:

- (void)collectionView:(UICollectionView *)collectionView didDeselectItemAtIndexPath:(NSIndexPath *)indexPath

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

   - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath

Ответ 2

Вы должны изменить внешний вид ячейки в методе делегата метода DidSelect и DidDeselect. Если возвращать НЕТ в метод shouldSelect, DidSelect и DidDeselect не будут вызываться, поэтому внешний вид останется неизменным, в соответствии с выбранным статусом collectionView.

Ответ 3

Вы пробовали:

- (BOOL)collectionView:(UICollectionView *)collectionView shouldDeselectItemAtIndexPath:(NSIndexPath *)indexPath

Я обнаружил, что это сработало по своему желанию.

Ответ 4

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

Причина, по которой - setSelected: вызывается несколько раз, вызвана вызванными методами последовательности. Последовательность очень похожа на последовательность методов UITextFieldDelegate.

Метод - collectionView:shouldSelectItemAtIndexPath: вызывается до того, как collectionView действительно выбирает ячейку, потому что она действительно запрашивает "следует ли ее выбрать"?

- collectionView:didSelectItemAtIndexPath: фактически вызывается после того, как collectionView выбирает ячейку. Следовательно, имя "сделал выбор".

То же самое относится к отмене выбора.

TL; DR - Отмените выделение collectionView на ячейку в методе делегата - collectionView:shouldSelectItemAtIndexPath:, вызвав - selectItemAtIndexPath:animated:scrollPosition:, и все будет в порядке.

Ответ 5

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

Подходы, которые не работают для меня:

  • Установка свойства cell selected в значение true или даже переключение на него false, а затем true.
  • Выбор элемента с помощью -selectItemAtIndexPath:animated:scrollPosition: или даже снятие выделения с помощью -deselectItemAtIndexPath:, а затем его повторное использование.
  • Перезагрузка только выбранных строк с помощью -reloadItemsAtIndexPaths:
  • Перезагрузка всего с помощью -reloadData.

Ответ 6

Я решил это, установив self.collectionView.allowsMultipleSelection = true.

И отменив выбор каждого индекса, когда я вернул true в -collectionView:shouldSelectItemAtIndexPath: