Check si UITableViewCell a été cliquée

KeiroMidoriKeiroMidori Membre
janvier 2014 modifié dans API UIKit #1

Bonjour à  tous !


 


J'ai un petit soucis pas très compliqué mais assez ennuyant. Je vous explique.


J'ai une UITableView avec une vingtaine de cells. Je set une image à  chaque cell. L'objectif que j'ai c'est de mettre une image différente une fois que la cell a été cliquée, comme un mail noté comme lu. Dans un premier temps je voudrais juste changer l'image mais lorsque je scroll vers le bas j'ai l'impression que mes cells se répètent donc lorsque je clique sur la premiere cell 14 row plus bas une autre cell change d'image alors qu'elle ne devrait pas.


J'ai trouvé quelques solutions sur le net mais je ne comprend pas tout à  fait ce qui cloche. Ensuite je m'occuperais de la serialisation pour garder en mémoire les cells "deja lu".


 


J'espere que vous pourrez m'aider ! Merci d'avance pour votre aide !!


 


Voici le code de ma fonction didSelectRowAtIndexPath :



- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(@Section : %d, indexPath.section);

// Ici je set la nouvelle image quand je clique sur la Cell en question
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
cell.imageView.image = [UIImage imageNamed:@read];
NSLog(@Row : %d, indexPath.row);


DetailViewController *detail = [[DetailViewController alloc] initWithStyle:UITableViewStyleGrouped];
detail.item = (MWFeedItem *)itemsToDisplay[indexPath.row];

[self.navigationController pushViewController:detail animated:YES];
[self.tableView deselectRowAtIndexPath:indexPath animated:YES];
}


Mots clés:

Réponses

  • Salut !!


     


    Moi ce que je fais en général, c'est que je gère un objet qui sera la cellule de ta tableView (je vais l'appeler Cellule pour l'exemple, mais dans tout projet l'objet listé à  une fonction bien particulière donc le nom doit être bien explicite).


     


    On gère un tableau de cet objet (Normalement tu dois avoir un manager, contenant un singleton, qui fait ce boulot. Ici je vais l'appeler CelluleManager). Avec cette architecture tu devrais faire simplement cette ligne de code lors du "didSelectRowAtIndexPath" :



    // Retrieve cellule
    NSArray *cellules = [[CelluleManager sharedManager] cellules];
    Cellule *cellule = cellules[indexPath.row];

    // Update cellule
    [self updateCellule:cellule];

    Comme ça ici on a un code clair, on voit bien la fonction de ta méthode "didSelectRowAtIndexPath".  La méthode "updateCellule" est une méthode privée qui contiendra l'appel de ton "DetailViewController".


     


    Pour finir, je ferai un delegate entre ton TableViewController et ton DetailViewContoller, n'oublie pas la ligne de code super importante quand tu seras notifié par ton delegate



    -(void) willBackFromDetailViewController {
    // Ton code de retour
    ....

    // Refresh table view
    [self.tableView reloadData];
    }

    Le reloadData fait appel à  la méthode Apple : 



    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

    Qui doit prendre en compte le tableau de ton manager ([[CelluleManager sharedManager] cellules]) pour que toute ta liste soit mise à  jour simplement. En espérant avoir été clair et assez simple.


     


    PI : Au passage je ne comprend pas ton "[self.tableView deselectRowAtIndexPath:indexPath animated:YES];" ? Pourquoi tu fais appels à  cette méthode ?


     


    Bon courage ! 


     


    K.


  • CéroceCéroce Membre, Modérateur
    janvier 2014 modifié #3

    Ce n'est pas ainsi qu'il faut faire. En gros, tu n'as pas vraiment le contrôle sur l'affichage des cellules. Notamment, il existe un système de recyclage des cellules (voir la doc de UITableView).


    Si un message est lu:

    1) marquer dans le Modèle que le message est lu



    MYMail *mail = [self.mailList.mails objectAtIndex:indexPath.row];
    mail.read = YES;

    2) demander à  la table de recharger la cellule



    [self.tableview reloadRowsAtIndexPaths:@[;indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];

    3) - tableView:cellForRowAtIndexPath: va être appelée à  nouveau. Dedans:

     



    MYMail *mail = [self.mailList.mails objectAtIndex:indexPath.row];
    cell.imageView.image = mail.read? [UIImage imageNamed:@Read.png] : [UIImage imageNamed:@Unread.png];

  • Bonjour,


     


    Tout d'abord veuillez m'excuser du retard de ma réponse. Je développais une autre application professionnelle et cela m'a pris tout mon temps.


    Je suis repassé sur mon application perso et du coup j'ai trouvé la réponse à  ma question dans la réponse de Céroce. Merci beaucoup pour ton aide ! Je suis en train de réfléchir à  une façon d'enregistrer les articles lus, pour qu'au prochain lancement, je puisse a nouveau indiquer les articles ayant étés lus comme tels. Le problème étant qu'un article peut se rajouter à  tout moment la liste n'est donc pas fixe.


    Merci beaucoup pour vos réponses !


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