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.
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];
}
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)
}
}
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.
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.
Solution Swift 3
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath as IndexPath, animated: true)
}
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.
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 .
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;
}
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.
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:
Sélectionnez la séquence de déroulement créée à l'étape 1
Bonne chance.
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)
}
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.
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath as IndexPath, animated: true)
}
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
}
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.
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];
}