web-dev-qa-db-fra.com

Pourquoi UITableViewCell reste-t-il en surbrillance?

Qu'est-ce qui ferait qu'une cellule de vue de tableau reste en surbrillance après avoir été touchée? Je clique sur la cellule et je peux voir qu'elle reste en surbrillance lorsqu'une vue détaillée est activée. Une fois la vue détaillée affichée, la cellule est toujours en surbrillance.

134
4thSpace

Dans votre didSelectRowAtIndexPath, vous devez appeler deselectRowAtIndexPath pour désélectionner la cellule.

Donc, quoi que vous fassiez dans didSelectRowAtIndexPath, vous devez simplement appeler aussi deselectRowAtIndexPath.

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
 // Do some stuff when the row is selected
 [tableView deselectRowAtIndexPath:indexPath animated:YES];
}
250
paulthenerd

La façon la plus propre de le faire est de voirWillAppear:

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    // Unselect the selected row if any
    NSIndexPath*    selection = [self.tableView indexPathForSelectedRow];
    if (selection) {
        [self.tableView deselectRowAtIndexPath:selection animated:YES];
    }
}

De cette façon, vous obtenez l’animation d’aplanir la sélection lorsque vous revenez au contrôleur, comme il se doit.

Tiré de http://forums.macrumors.com/showthread.php?t=577677

Version rapide

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)

    // deselect the selected row if any
    let selectedRow: IndexPath? = tableView.indexPathForSelectedRow
    if let selectedRowNotNill = selectedRow {
        tableView.deselectRow(at: selectedRowNotNill, animated: true)
    }
}
56
Danail

Avez-vous sous-classe -(void)viewWillAppear:(BOOL)animated? La UITableViewCell sélectionnée ne sera pas désélectionnée si vous n'appelez pas [super viewWillAppear:animated]; dans votre méthode personnalisée.

20
HansPinckaers

Pour les utilisateurs de Swift, ajoutez ceci à votre code: 

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    tableView.deselectRowAtIndexPath(indexPath, animated: true)
}

C'est la réponse de paulthenerd sauf dans Swift au lieu de Obj-C. 

17
Rutger Huijsmans

Solution Swift 3

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
      tableView.deselectRow(at: indexPath as IndexPath, animated: true)
}
9
Oscar

Si vous utilisez un UITableViewCell, alors commentez la ligne suivante 

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

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

}

J'espère que cela t'aides.

7
Shantanu Phate

Mis à jour avec Swift 4

Après quelques expériences, également basées sur des réponses précédentes, j'ai conclu que le meilleur comportement peut être obtenu de 2 manières: (presque identique dans la pratique)

// First Solution: delegate of the table View
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    tableView.deselectRow(at: indexPath, animated: false)
}

// Second Solution: With the life cycle of the view.
override func viewDidDisappear(_ animated: Bool) {
    super.viewDidDisappear(animated)

    let selectedRow: IndexPath? = tableView.indexPathForSelectedRow
    if let selectedRow = selectedRow {
        tableView.deselectRow(at: selectedRow, animated: false)
    }
}

Personnellement, j'adopte la première solution, car elle est simplement plus concise. Une autre possibilité, si vous avez besoin d’une petite animation lorsque vous revenez à votre tableView, est d’utiliser viewWillAppear:

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)

    let selectedRow: IndexPath? = _view.tableView.indexPathForSelectedRow
    if let selectedRow = selectedRow {
        _view.tableView.deselectRow(at: selectedRow, animated: true)
    }
}

Enfin, si vous utilisez un UITableViewController, vous pouvez également tirer parti de la propriété clearsSelectionOnViewWillAppear

3

Pour obtenir le comportement décrit par Kendall Helmstetter Gelner dans son commentaire, vous ne voulez probablement pas deselectRowAtIndexPath, mais plutôt la propriété clearsSelectionOnViewWillAppear de votre contrôleur. Peut-être que cela a été réglé sur OUI par accident? 

Voir le commentaire dans le modèle Apple par défaut pour les nouvelles sous-classes UITableViewController:

- (void)viewDidLoad
{
    [super viewDidLoad];

    // Uncomment the following line to preserve selection between presentations.
    // self.clearsSelectionOnViewWillAppear = NO;
}
3
Dave Teare

J'avais aussi ce problème pour mon application d'exploration en aval. Après qu'un contrôleur de vue, que j'appellerai VC, revienne après avoir appuyé sur un autre contrôleur de contrôle, la cellule sélectionnée dans VC est restée en surbrillance. Dans mon application, j'avais créé VC pour gérer le deuxième niveau (sur trois niveaux) de mon analyse descendante.

Le problème dans mon cas est que VC était un UIViewController (qui contenait une vue contenant une tableView). J'ai plutôt fait VC un UITableViewController (qui contenait un TableView). La classe UITableViewController gère automatiquement la dé-surbrillance de la cellule de tableau après son retour d'un Push. La deuxième réponse au message " Problème avec deselectRowAtIndexPath dans tableView " donne une réponse plus complète à ce problème.

Le problème ne s'est pas posé pour le contrôleur de vue racine, car lorsque j'ai créé l'application en tant qu '"application basée sur la navigation" dans XCode, le contrôleur de vue racine résultant était déjà défini dans la sous-classe UITableViewController.

2

Si aucune de ces solutions ne vous convient, envisagez cette solution:

Utilisez un appel téléphonique pour appeler:

@IBAction func unwind_ToTableVC (segue: UIStoryboardSegue) {
    if let index = tableView.indexPathForSelectedRow {
        tableView.deselectRowAtIndexPath(index, animated: true)
    }
}

Pourquoi faire ceci? Principalement si vous rencontrez des difficultés pour obtenir le code de désélection de fonctionner au bon moment. J'avais du mal à ne pas travailler avec le viewWillAppear, ce qui a bien fonctionné.

Pas:

  1. Écrivez la séquence de déroulement (ou collez par dessus) dans votre premier VC (celui avec la table)
  2. Allez au 2e VC. Tout en maintenant la touche Ctrl enfoncée, faites glisser le bouton Annuler/Terminé/Etc utilisé pour ignorer VC, puis faites-la glisser vers l'icône de sortie en haut.
  3. Sélectionnez la séquence de déroulement créée à l'étape 1

    Bonne chance.

1
Dave G

J'utilise Core Data, donc le code qui a fonctionné pour moi était une combinaison d'idées de différentes réponses, dans Swift:

override func viewDidAppear(_ animated: Bool) {
    if let testSelected = yourTable.indexPathForSelectedRow {
        yourTable.deselectRow(at: testSelected, animated: true)
    }
    super.viewDidAppear(true)
}
1
Yewzr

Xcode 10, Swift 4

J'ai eu ce même problème et j'ai découvert que j'avais laissé un appel vide à viewWillAppear au bas de mon tableViewController. Une fois que j'ai supprimé la fonction de remplacement vide, la ligne n'est plus restée en surbrillance lors du retour à la vue table.

problème de fonctionnement

override func viewWillAppear(_ animated: Bool) {
  // need to remove this function if not being used.
}

supprimer la fonction vide a résolu mon problème.

0
Robac
 func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    tableView.deselectRow(at: indexPath as IndexPath, animated: true)
}
0
Mob

Pour Swift 3: Je préférerais qu'il soit utilisé dans viewDidDisappear

Définir:-

    var selectedIndexPath = IndexPath()

Dans viewDidDisappear: -

    override func viewDidDisappear(_ animated: Bool) {
    yourTableView.deselectRow(at: selectedIndexPath, animated: true)
}

Dans didSelectRowAtIndexPath: -

    func tableView(_ tableView: UITableView, didSelectRowAtIndexPath indexPath: IndexPath) {
    selectedIndexPath = indexPath
}
0
Irshad Qureshi

J'ai le même problème depuis longtemps, donc au cas où quelqu'un d'autre aurait du mal à se battre:

Examinez votre -tableView: cellForRowAtIndexPath: et voyez si vous créez des cellules ou utilisez un «identifiant de réutilisation». Si c'est le cas, assurez-vous que votre table dans IB a une cellule avec cet identifiant. Si vous n'utilisez pas d'identificateur de réutilisation, créez simplement une nouvelle cellule pour chaque ligne.

Cela devrait ensuite donner à votre table le «fondu sélectionné» attendu lors de son apparition.

0
LearningAsIGo

Utilisez cette méthode dans la classe UITableViewCell 

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

   // Just comment This line of code
   // [super setSelected:selected animated:animated];        
}
0
sunny