La première chose que je fais est de définir la cellule sélectionnée.
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"Cell" forIndexPath:indexPath];
cell.selected = YES;
return cell;
}
Et la cellule est sélectionnée avec succès ... Si l'utilisateur touche la cellule sélectionnée, la cellule doit être désélectionnée et les délégués appelés. Mais cela n'arrive jamais.
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
NSLog(@"%s", __PRETTY_FUNCTION__);
}
- (void)collectionView:(UICollectionView *)collectionView didDeselectItemAtIndexPath:(NSIndexPath *)indexPath {
NSLog(@"%s", __PRETTY_FUNCTION__);
}
Je sais que les délégués ne sont pas appelés si je configure la sélection par programme. Le délégué et la source de données sont définis.
Cependant, ce délégué s'appelle:
- (BOOL)collectionView:(UICollectionView *)collectionView shouldHighlightItemAtIndexPath:(NSIndexPath *)indexPath {
NSLog(@"%s", __PRETTY_FUNCTION__);
return YES;
}
Si je supprime le cell.selected = YES
que tout fonctionne. Y a-t-il quelqu'un qui peut m'expliquer ce comportement?
Le problème est que la cellule est sélectionnée mais que UICollectionView
n'en sait rien. Un appel supplémentaire pour la UICollectionView
résout le problème:
[collectionView selectItemAtIndexPath:indexPath animated:NO scrollPosition:UICollectionViewScrollPositionNone];
Code complet:
- (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;
}
Je garde la question pour aider quelqu'un qui pourrait être confronté au même problème.
Je pense que la solution fournie par @zeiteisen est un moyen de contourner la solution. La vraie chose réside dans le mode de sélection. Il n'y a rien à définir dans la propriété cell.selected
.
Il existe deux propriétés de UICollectionView
name allowsMultipleSelection
et allowsSelection
.
allowsMultipleSelection
est NO
par défaut et allowsSelection
est YES
.
Si vous souhaitez sélectionner une seule cellule, le code @ l'initialisation se présente comme suit:
yourCollectionView.allowsMultipleSelection = NO;
yourCollectionView.allowsSelection = YES; //this is set by default
Ensuite, les paramètres vous permettront de sélectionner une seule cellule à la fois, pas moins, pas plus. Vous devez sélectionner au moins une cellule. La didDeselectItemAtIndexPath
ne sera pas appelée à moins que vous ne sélectionniez une autre cellule. Taper sur une UICollectionViewCell
déjà sélectionnée ne le fera pas sur Désélectionner. C'est la politique derrière la mise en œuvre.
Si vous souhaitez sélectionner plusieurs cellules, le code @ l'initialisation doit ressembler à ceci:
yourCollectionView.allowsMultipleSelection = YES;
yourCollectionView.allowsSelection = YES; //this is set by default
Ensuite, les paramètres permettront de sélectionner plusieurs cellules. Ces paramètres ne permettent à aucun ou à plusieurs UICollectionViewCell
d'être sélectionné. Le nombre de cellules sélectionnées sera
0 <= number_selected_cell <= total_number_of_cell
C'est la politique derrière la sélection de cellules multiples.
Si vous avez l’intention d’utiliser l’un des éléments ci-dessus, vous pouvez utiliser l’API Apple sans mal de tête, sinon vous devez trouver un moyen de vous faufiler dans votre objectif en utilisant votre propre code ou l’API d’Apple.
J'ai eu le même problème. J'ai présélectionné des cellules lors du chargement de la table, mais je devais appuyer deux fois sur une cellule pour la désélectionner. @zeiteisen répondre m'a aidé. Cependant, je travaille dans Swift 3 et j’ai donc pensé donner une réponse dans 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
}
Ajouter cette ligne à votre méthode didSelectItemAtIndexPath
[collectionView selectItemAtIndexPath:indexPath animated:NO scrollPosition:nil]
Dans mon cas, cela a été causé en utilisant la même logique pour
func collectionView(_ collectionView: UICollectionView, shouldHighlightItemAt indexPath: IndexPath) -> Bool
pour ce qui est de
func collectionView(_ collectionView: UICollectionView, shouldSelectItemAt indexPath: IndexPath) -> Bool
Et quand la cellule a été sélectionnée devraitHighlightItemAt retournait faux - et cela m'a empêché de désélectionner cette cellule.
J'espère que cela fera gagner du temps à quelqu'un :)
Recharger la cellule était une solution pour moi. Ce dont j'avais besoin, c'était de changer d'image en cellule pendant un bref instant. J'assigne image à imageView dans cellForItemAtIndexPath et lorsque l'utilisateur touche la cellule, je change d'image et lance mycode, puis recharge la cellule.
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])
}
J'espère que ça aide quelqu'un.