selection - didselectitematindexpath - uicollectionview selected cell
UICollectionView shouldSelectItemAtIndexPath=NO ¿no evita deseleccionar la selección anterior? (6)
Tengo varios elementos en un CollectionView, pero solo algunos de ellos deberían ser seleccionables. Estoy manejando esto con el método de delegado:
- (BOOL)collectionView:(UICollectionView *)collectionView shouldSelectItemAtIndexPath:(NSIndexPath *)indexPath
Mi problema ocurre si se selecciona un elemento seleccionable y en el siguiente paso la selección de un elemento no seleccionable es rechazada por shouldSelectItemAtIndexPath que devuelve NO, el elemento seleccionado se deselecciona de todos modos.
También he tratado de usar
- (BOOL)collectionView:(UICollectionView *)collectionView shouldHighlightItemAtIndexPath:(NSIndexPath *)indexPath
Pero es el mismo problema.
¿Es este el correcto comportamiento deseado de UICollectionView? Y si es así, ¿cómo puedo evitar la deselección de mi último elemento seleccionado si se selecciona un elemento no seleccionable?
Acabo de tener este mismo problema. Probé una variedad de soluciones y la primera que funcionó en mi caso fue volver a cargar y luego volver a seleccionar las celdas seleccionadas. Esto me funcionó ya sea que recargué la vista de colección completa o solo las celdas que se atascaron con una apariencia no seleccionada.
Enfoques que no funcionaron para mí:
- Estableciendo la propiedad
selected
la celda en verdadero, o incluso cambiándola a falso y luego a verdadero nuevamente. - Seleccionando el elemento mediante
-selectItemAtIndexPath:animated:scrollPosition:
o incluso deseleccionándolo mediante-deselectItemAtIndexPath:
y luego seleccionándolo nuevamente. - Recargando solo las filas seleccionadas con
-reloadItemsAtIndexPaths:
-
-reloadData
todo con-reloadData
.
Debe cambiar la apariencia de la celda en el método delegado DidSelect y DidDeselect. Si se devuelve NO en el método shouldSelect, no se invocará DidSelect y DidDeselect, por lo que la apariencia se mantendrá igual, en consonancia con el estado seleccionado de collectionView.
Has probado:
- (BOOL)collectionView:(UICollectionView *)collectionView shouldDeselectItemAtIndexPath:(NSIndexPath *)indexPath
Encontré que esto funcionó como se desea.
No sé por qué UICollectionView
es tan desordenado como esto en comparación con UITableViewController
... Algunas cosas que descubrí.
La razón por la que - setSelected:
se llama varias veces es debido a los métodos de secuencia que se llaman. La secuencia es muy similar a la de los métodos UITextFieldDelegate
.
Se llama al método - collectionView:shouldSelectItemAtIndexPath:
antes de que collectionView
realmente seleccione la celda porque en realidad está preguntando "¿debería seleccionarse"?
- collectionView:didSelectItemAtIndexPath:
de hecho se llama después de que collectionView
selecciona la celda. De ahí el nombre "seleccioné".
Lo mismo ocurre con la deselección.
TL; DR - collectionView:shouldSelectItemAtIndexPath:
su collectionView
deseleccione la celda en el método delegado - collectionView:shouldSelectItemAtIndexPath:
llamando - selectItemAtIndexPath:animated:scrollPosition:
y todo estará bien.
Tengo que corregir mi suposición: ¡ La última selección no se deseleccionará!
Para cambiar la apariencia de la celda en la selección, he anulado el acceso setSelected de UICollectionViewCell. Al seleccionar un elemento no seleccionable, se llama varias veces al conjunto de accesores seleccionado de la última celda seleccionada. Primero con el estado NO, luego con el estado SÍ y al final con NO nuevamente. El último estado NO hizo que mi celda configurara su apariencia como la de una celda no seleccionada.
No sé la razón de este extraño comportamiento ni podría resolverlo.
Mi solución es cambiar la apariencia de las celdas seleccionadas directamente en ViewController.
Establece la apariencia seleccionada en:
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
Eliminar el aspecto seleccionado:
- (void)collectionView:(UICollectionView *)collectionView didDeselectItemAtIndexPath:(NSIndexPath *)indexPath
Compruebe si la celda actual está seleccionada y cambie la apariencia según lo previsto.
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
self.collectionView.allowsMultipleSelection = true
esto configurando self.collectionView.allowsMultipleSelection = true
.
Y deseleccionando cada índice cuando -collectionView:shouldSelectItemAtIndexPath:
verdadero a -collectionView:shouldSelectItemAtIndexPath: