UICollectionView shouldSelectItemAtIndexPath = NO не позволяет отказаться от выбора старого выбора?
У меня есть несколько элементов в CollectionView, но только некоторые из них должны быть доступны. Я обрабатываю это методом делегата:
- (BOOL)collectionView:(UICollectionView *)collectionView shouldSelectItemAtIndexPath:(NSIndexPath *)indexPath
Моя проблема возникает, если выбран выбранный элемент, и на следующем шаге выбор не выбираемого элемента отклоняется ifSelectItemAtIndexPath, возвращающим NO, выбранный элемент все равно отменяется.
Я также пытался использовать
- (BOOL)collectionView:(UICollectionView *)collectionView shouldHighlightItemAtIndexPath:(NSIndexPath *)indexPath
Но это та же проблема.
Является ли это правильным желаемым поведением UICollectionView? И если да, как я могу избежать отмены моего последнего выбранного элемента, если выбран не выбранный элемент?
Ответы
Ответ 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: