web-dev-qa-db-fra.com

les cellules iPhone UITableView restent sélectionnées

dans mon UITableView, parfois, les cellules restent sélectionnées après avoir touché . Parce que cela n'arrive que de temps en temps, je ne peux pas reproduire le problème

Des allusions? Peut-être cela a-t-il quelque chose à voir avec la publication inappropriée de tableView?

    - (void)tableView:(UITableView *)tableView 
    didSelectRowAtIndexPath:(NSIndexPath *)indexPath{   
    NSUInteger row = [indexPath row];

    [tableView deselectRowAtIndexPath:indexPath animated:YES];

switch (row) {
    case 0:
        FruitViewController *fruitController = [FruitViewController alloc];
        [fruitController retain];
        [fruitController initWithNibName:@"FruitView" bundle:[NSBundle mainBundle]];
        [self.navigationController pushViewController:fruitController animated:YES];
        [fruitController release];
        break;
    case 1: 
        CerealsViewController *cerealsController = [CerealsViewController alloc];
        [cerealsController retain];
        [cerealsController initWithNibName:@"CerealsView" bundle:[NSBundle mainBundle]];
        [self.navigationController pushViewController:cerealsController animated:YES];
        [cerealsController release];
        break;
    default:
        break;   
}
   }
45
Stefan

Je ne peux pas vous dire pourquoi vous voyez le problème, mais voici quelques suggestions pour le résoudre:

Selon Apple HIG, la sélection ne devrait pas disparaître avant de revenir du contrôleur de vue simplement poussé sur la pile. Si votre contrôleur est juste un UITableViewController, il devrait se désélectionner automatiquement lors du retour à la vue. Si non, ajoutez

- (void) viewWillAppear:(BOOL)animated {
    [tableView deselectRowAtIndexPath:[tableView indexPathForSelectedRow] animated:animated];
    [super viewWillAppear:animated];
}

quelque part dans le contrôleur de vue.

Si des lignes ne permettent pas d'accéder à une autre vue et ne font rien lorsqu'elles sont sélectionnées, elles ne doivent pas pouvoir être sélectionnées.

- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath

et renvoie nil dans les cas où la ligne ne doit pas être sélectionnée.

98
Ed Marty

Une cause possible est de remplacer -viewWillAppear:animated: sans appeler [super viewWillAppear] dans un contrôleur qui étend UITableViewController. L'ajout de [super viewWillAppear:animated] au début de votre méthode -viewWillAppear peut résoudre le problème.

21
Fiid

Juste pour développer la réponse de "Ed Marty", j’ai choisi d’ajouter la désélection dans la méthode "viewWillDisappear" parce que j’ai pensé qu’elle était plus jolie. 

En plus de cela, j'utilisais une UITableView avec un UIViewController normal (plutôt qu'un UITableViewController), de sorte que la variable tableView n'était pas disponible pour moi. Pour résoudre ce problème, j'ai ajouté une propriété tableView dans mon fichier d'en-tête de contrôleurs de vue (et dans mon fichier XIB, j'ai connecté la vue tabulaire réelle à la propriété) ...

@property (nonatomic,retain) IBOutlet UITableView *tableView

... et dans l'implémentation des contrôleurs de vue ont câblé la propriété et effectué la désélection comme suit.

@synthesize tableView

- (void) viewWillDisappear:(BOOL)animated {
    [self.tableView deselectRowAtIndexPath:[self.tableView indexPathForSelectedRow] animated:animated];
    [super viewWillDisappear:animated];
}
11
Oliver Pearmain

Si vous utilisez un UITableViewController, vous pouvez utiliser: 

self.clearsSelectionOnViewWillAppear = YES;
8
Pach

Dans mon cas, je désélectionne la cellule à la fin de didSelectRowAtIndexPath: 

  - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

    // Do smth here. segue ..etc

    [tableView deselectRowAtIndexPath:[tableView indexPathForSelectedRow] animated:NO];
}
4
helloiloveit

Utilisez cette méthode dans votre classe UITableViewCell

(void)setSelected:(BOOL)selected animated:(BOOL)animated {

// Just comment This line of code

// [super setSelected:selected animated:animated];

}

ou même vous pouvez essayer ce code dans la méthode didSelectRowAtIndexPath

- (void) tableView: (UITableView *) tableView didSelectRowAtIndexPath: (NSIndexPath *) indexPath {

// Fait des trucs quand la rangée est sélectionnée

[tableView deselectRowAtIndexPath:indexPath animated:YES];

}

0
sunny

La résolution de ce problème prend environ deux secondes une fois que vous avez appris à gérer les tables. 

Dès que les cellules sortent de l'écran, elles perdent leur formatage. La table réduit son utilisation de la mémoire en supprimant les autres cellules et en les recréant si/lorsque l'utilisateur fait défiler en arrière.

Même des choses comme le rechargement de données de table, cela ne s'applique vraiment qu'aux cellules à l'écran à ce moment. Cela dit, cellForRowAtIndexPath peut créer la même cellule cinq fois sans que l'utilisateur n'appuie sur un bouton ou quitte le contrôleur de vue! Alors configurez-le pour recharger toute mise en forme. Ajoutez quelque chose comme ceci à cellForRowAtIndexPath:

    if arrayOf_SelectedCells.contains(indexPath) {
        setup_Selected(cell)
        //Where setup_Selected is a custom function to apply formatt
    } else {
        setup_Unselected(cell)
    }
0
Dave G