web-dev-qa-db-fra.com

UItableViewCell sélectionné reste bleu lorsqu'il est sélectionné

Lorsque je pousse une vue après qu'un utilisateur a sélectionné une ligne UITableView, la ligne est mise en surbrillance bleue, puis la nouvelle vue apparaît. C'est très bien. Mais quand je reviens en arrière, la ligne est toujours surlignée en bleu. Voici mon code didSelectRowAtIndexPath.

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    SettingsViewController *controller = [[SettingsViewController alloc] initWithNibName:@"SettingsView" bundle:nil];
    [[self navigationController] pushViewController:controller animated:YES];
    [controller release], controller = nil; 
}

Qu'est-ce que je fais mal?

55
cannyboy

Comme le soulignent les réponses ci-dessus, vous devez désélectionner explicitement la ligne. Vous avez deux options quant à la façon de procéder. La première consiste à désélectionner la ligne immédiatement après la sélection:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
  ...
  [tableView deselectRowAtIndexPath:indexPath animated:YES];
}

Cela fonctionnera très bien, mais il existe une alternative, et c'est l'approche adoptée par UITableViewController qui consiste à laisser la ligne sélectionnée puis à la désélectionner lorsque la vue réapparaît (après que le contrôleur que vous appuyez est sauté) hors de la pile).

Cela a le léger avantage que l'utilisateur voit un aperçu de sa sélection précédente à son retour afin de pouvoir voir ce qu'il avait précédemment sélectionné.

Pour l'implémenter, il vous suffit de remplacer viewWillAppear:

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

Comme je l'ai dit, c'est ce que l'implémentation par défaut de UITableViewController est viewWillAppear: le fait si vous utilisez UITableViewController et ne pas voir ce comportement, vous devez vérifier que vous appelez le super implémentation dans votre propre classe viewDidAppear:.

Mise à jour (30 octobre 2013): eh bien, c'est une réponse populaire! Comme Ben le fait remarquer à juste titre dans les commentaires, UITableViewController le fait en fait dans viewWillAppear: ne pas viewDidAppear: - c'est le bon timing. En outre, vous activez et désactivez ce comportement à l'aide de la propriété clearsSelectionOnViewWillAppear de UITableViewController. J'ai modifié ma réponse ci-dessus pour refléter cela.

171
Luke Redpath

UITableViewController possède une propriété BOOL appelée clearsSelectionOnViewWillAppear qui fait exactement ce que vous voulez.

Par défaut, il est défini sur YES, mais j'ai remarqué que vous pouvez (parfois accidentellement) désactiver cette propriété en implémentant votre propre viewWillAppear: méthode. Je pense que c'est parce que la désélection se produit pendant [UITableViewController viewWillAppear:] qui pourrait ne jamais être appelé si vous le remplacez.

La solution est alors simple. Appelez simplement la version super de viewWillAppear: quelque part dans votre version de cette méthode:

- (void)viewWillAppear:(BOOL)animated {
  // Your custom code.
  [super viewWillAppear:animated];
}

Apple recommande de toujours appeler la super version de l'une des méthodes d'affichage {Did, Will} {A, Disa} ppear si vous les remplacez.

Références

11
Tyler

Vous devez le désélectionner:

[tableView deselectRowAtIndexPath:indexPath animated:YES];

7
pkananen

Si votre contrôleur est basé sur UITableViewController, vous obtenez cette fonctionnalité gratuitement. Mais j'ai souvent fini par utiliser UIViewController sans. d'autres contrôles en plus de UITableView, dans ce cas, vous devez remplacer votre viewWillAppear par

-(void) viewWillAppear:(BOOL)animated{
    // Unselect the selected row if any
    NSIndexPath*    selection = [devListTableview indexPathForSelectedRow];
    if (selection){
        [tableview deselectRowAtIndexPath:selection animated:YES];
    }
}
4
palaniraja

Il vous suffit d'appeler [tableView deselectRowAtIndexPath: indexPath animated: YES].

3
Ben Gottlieb

Le comportement par défaut de UITableViewController désélectionne la ligne lorsque l'utilisateur revient de la vue détaillée. La réponse donnée par Luke est très bien, mais je veux en expliquer la raison:

1- Si vous avez votre UITableViewController tel qu'il était lorsque vous l'avez créé à partir de zéro, vous aurez tous les comportements par défaut.

2- Si dans la situation 1 vous ajoutez un -viewWillAppear ou -viewDidAppear, alors vous écraserez le comportement standard. Eux, si vous voulez que la ligne soit désélectionnée au retour, vous devez dire explicitement le super que vous souhaitez qu'il désélectionne lui-même la ligne comme il l'a toujours fait! Pour ce faire, comme le dit Luke, vous devez appeler [super viewWillAppear:animated] ou [super viewDidAppear:animated] comme ça:

-(void)viewWillAppear:(BOOL)animated {

    [super viewWillAppear:animated];

    // Here goes all of your stuff
}
2
Ruben Marin

Une autre solution consiste à appeler reloadData d'UITableView dans viewWillAppear

0
Andy A