[Rà‰SOLU] UICollectionView et IBAction

BenjoBenjo Membre
juillet 2013 modifié dans API UIKit #1

Bonjour à  tous


 


J'ai un petit problème dans mon projet, surement très simple à  résoudre, mais sur lequel j'ai beaucoup de mal à  me sortir. Je m'explique :


J'ai une collectionView composée de plusieurs sections (principaux, trigonometrie et avance). Les cellules de ma collectionView sont composées d'un UIButton. En fait, j'aimerais que dans chaque section, les boutons aient une action différente. Par exemple, la section "principaux" auraient comme action "action1", "trigonometrie" "action2" et ainsi de suite.


Je ne sais pas si je suis très clair alors j'ai réalisé un schéma du résultat attendu.


 


Pour attribuer mes actions dans chaque section, j'utilise ce code :



- (void)viewDidLoad
{
[super viewDidLoad];

principaux = [[NSArray alloc] initWithObjects:@√, @1/x, @x√y, @%, @LOG, @INT, @LN, @MOD, nil];
trigonometrie = [[NSArray alloc] initWithObjects:@COS, @COSH, @SIN, @SINH, @TAN, @TANH, @COTAN, @COTANH, nil];
avances = [[NSArray alloc] initWithObjects:@DEG/RAD, @x=0, @H, @x>0, @P, @x>y, @LR, @x≥y, nil];

//Bouton rassemble tous les boutons listés au dessus
boutons = [NSArray arrayWithObjects:principaux, trigonometrie, avances, nil];
}


-(NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
return boutons.count;
}

-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
return [[boutons objectAtIndex:section] count];
}

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

static NSString *identifiant = @identifiant;

//Configuration des cellules
BoutonFonctions *cell = [fonctions dequeueReusableCellWithReuseIdentifier:identifiant forIndexPath:indexPath];

[cell.bouton setTitle:[boutons[indexPath.section] objectAtIndex:indexPath.row] forState:UIControlStateNormal];
[cell.bouton setTag:indexPath.item];


if (indexPath.section == 0) {
[cell.bouton addTarget:self action:@selector(page1t:) forControlEvents:UIControlEventTouchUpInside];
}
else if (indexPath.section == 1) {
[cell.bouton addTarget:self action:@selector(trigonometrie:) forControlEvents:UIControlEventTouchUpInside];
}

return cell;
}

Lorsque je clique sur un bouton de la section 2, il exécute page1t qui est normalement destinée à  la section 1.


 


Est-ce que quelqu'un a une idée sur ce problème ?


 


Merci d'avance :)


Réponses

  • AliGatorAliGator Membre, Modérateur
    Tu as oublié que les cellules d'une tableView sont recyclées. Et qu'un UIControl (comme par exemple un UIButton) peut avoir autant de couples target/action qu'il veut.


    Donc ce qui se passe certainement c'est que tu ajoutes le @selector( page1t: ) au bouton, puis tes cellules sont réutilisées, puis tu ajoutes @selector( trigonometrie: ) à  ton bouton qui avait déjà  l'action page1t et se retrouve donc avec les 2 actions. Si tu continues à  recycler tes cellules tu ne vas pas arrêter d'ajouter des actions à  tes boutons, tantôt l'une tantôt l'autre, sans supprimer les précédentes...


    Il faut penser donc à  faire un removeAllActionsForControlEvent: (ou un truc comme ça, je le cite de mémoire) sur ton bouton pour enlever les actions précédentes avant de rappliquer une nouvelle action.
  • BenjoBenjo Membre
    juillet 2013 modifié #3

    Merci AliGator pour ta réponse rapide.


    J'avais déjà  essayé un truc comme ça :



    [cell.bouton removeTarget:nil action:nil forControlEvents:UIControlEventAllEvents];

    if (indexPath.section == 0) {
    [cell.bouton addTarget:self action:@selector(page1t:) forControlEvents:UIControlEventTouchUpInside];
    }
    else if (indexPath.section == 1) {
    [cell.bouton addTarget:self action:@selector(trigonometrie:) forControlEvents:UIControlEventTouchUpInside];
    }

    return cell;

    Mais ça ne marche toujours pas. Mais en fait ici je n'enlève aucune action puisque "action:nil". Alors comment savoir quelle action il faut enlever sans avoir à  multiplier les lignes de code ?


  • AliGatorAliGator Membre, Modérateur
    D'après la doc quand tu passes NULL au paramètre "action:" ça enlève bien toutes les actions.


    Cela doit donc résoudre le problème du reuse (que tu n'avais peut-être pas encore remarqué surtout si ta CollectionView ne scroll pas et que tout est déjà  affiché et don qu'en pratique le reuse n'est pas déclenché) mais cela n'empêche pas qu'il doit y avoir un autre problème.


    Que disent tes logs ou ton debug en mode pas à  pas ?
  • J'ai réessayé ta solution du "removeTarget:nil action:nil forControlEvents:" ça ne marchait pas ce matin mais après avoir redémarré Xcode ça fonctionnait et chaque bouton exécutait bien la bonne action. Un petit bug de Xcode surement...


    Merci beaucoup AliGator pour ta solution !


Connectez-vous ou Inscrivez-vous pour répondre.