UICollectionView-didDeselectItemAtIndexPath no se llama si se selecciona cell


Lo primero que hago es establecer la celda seleccionada.

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

Y la celda se selecciona correctamente. Si el usuario toca la celda seleccionada, entonces la celda debe ser deseleccionada y los delegados deben ser llamados. Pero esto nunca pasa.

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

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

Sé que los delegados no son llamados si establezco la selección programáticamente. Se establecen el delegado y el origen de datos.

Sin embargo, este delegado es llamado:

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

Si elimino el cell.selected = YES entonces todo está funcionando. Ser ¿hay alguien que pueda explicar este comportamiento?

Author: zeiteisen, 2013-12-04

5 answers

El problema es que la celda está seleccionada, pero el UICollectionView no sabe nada al respecto. Una llamada extra para el UICollectionView resuelve el problema:

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

Código completo:

- (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;
}

Guardo la pregunta para ayudar a alguien que puede enfrentar el mismo problema.

 54
Author: zeiteisen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-12-04 16:28:32

Creo que la solución que @zeiteisen proporcionó es una solución alternativa. La cosa real se encuentra en el modo de selección. No hay nada para establecer la propiedad in cell.selected.

Hay dos propiedades del nombre UICollectionView allowsMultipleSelection y allowsSelection.

allowsMultipleSelection es NO por defecto y allowsSelection es YES.

Si desea seleccionar solo una celda, entonces el código @la inicialización se ve como

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

Entonces la configuración le permitirá seleccionar solo una celda a la vez, no menos no mas. Debe tener que seleccionar al menos una celda. El didDeselectItemAtIndexPath no será llamado a menos que seleccione otra celda. Tocar un UICollectionViewCell ya seleccionado no hará que se deseleccione. Esta es la política detrás de la implementación.

Si desea seleccionar varias celdas, entonces el código @la inicialización debería tener el siguiente aspecto:

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

Entonces la configuración permitirá seleccionar varias celdas. Esta configuración permite seleccionar ninguno o múltiples UICollectionViewCell. Número de células seleccionado será

0 <= number_selected_cell <= total_number_of_cell

Esta es la política detrás de la selección de celdas múltiples.

Si tiene la intención de usar cualquiera de los anteriores, puede usar apple api sin dolor de cabeza adicional, de lo contrario, debe encontrar una manera de colarse en su objetivo utilizando su propio código o la api de Apple.

 19
Author: Ratul Sharker,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-04-17 19:13:04

Tuve el mismo problema. Preseleccioné celdas al cargar la tabla, pero tuve que tocar dos veces una celda para deseleccionarla. @ zeiteisen respuesta me ayudó. Sin embargo, estoy trabajando en Swift 3, así que pensé en dar una respuesta en 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
}
 6
Author: Meagan S.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-12-16 20:28:56

Agregue esta línea a su método didSelectItemAtIndexPath

[collectionView selectItemAtIndexPath:indexPath animated:NO scrollPosition:nil]
 1
Author: Nupur Sharma,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-02-27 12:22:46

Recargar la celda fue la solución para mí. Lo que necesitaba era cambiar la imagen en la celda por un breve momento. Asigno imagen a ImageView en cellForItemAtIndexPath y cuando el usuario toca la celda, cambio la imagen y corro mycode y luego recargo la celda.

 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])
    }

Espero que ayude a alguien.

 0
Author: Yasin Nazlıcan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-09-01 14:59:52