Risposte:
Nel tuo didSelectRowAtIndexPathè necessario chiamare deselectRowAtIndexPathper deselezionare la cella.
Quindi qualsiasi altra cosa tu stia facendo, didSelectRowAtIndexPathdevi solo chiamarla deselectRowAtIndexPath.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// Do some stuff when the row is selected
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
-deselectRowAtIndexPath:animated:metodo sulla sua proprietà tableView da -viewDidAppear. Tuttavia, se si dispone di una vista tabella in una sottoclasse UIViewController, è necessario chiamare -deselectRowAtIndexPath:animated:da -viewDidAppearsoli. :)
-viewWillAppear:ciò che l'ha rotto. Aggiunta di una chiamata per [super viewWillAppear:animated]farla funzionare di nuovo.
UITableViewController's clearsSelectionOnViewWillAppearproprietà è impostata su YES(che è il default), e non è stato impedito [super viewWillAppear]di essere chiamato.
Il modo più pulito per farlo è su viewWillAppear:
- (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];
}
}
In questo modo hai l'animazione di sbiadire la selezione quando torni al controller, come dovrebbe essere.
Tratto da http://forums.macrumors.com/showthread.php?t=577677
Versione rapida
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)
}
}
viewDidAppearinvece.
indexPathForSelectedRowchiamata può restituire zero quindi dovrebbe essere verificata. La documentazione indica : un percorso di indice che identifica gli indici di riga e di sezione della riga selezionata o nullo se il percorso di indice non è valido.
Sei stato sottoclasse -(void)viewWillAppear:(BOOL)animated? UITableViewCell selezionato non verrà deselezionato quando non si chiama [super viewWillAppear:animated];il metodo personalizzato.
Per gli utenti di Swift, aggiungilo al tuo codice:
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
tableView.deselectRowAtIndexPath(indexPath, animated: true)
}
È la risposta di paulthenerd tranne che in Swift anziché in Obj-C.
Aggiornato con Swift 4
Dopo alcuni esperimenti, anche basati su risposte precedenti, ho la conclusione che il miglior comportamento può essere ottenuto in 2 modi: (quasi identico nella pratica)
// 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)
}
}
Personalmente sto adottando la prima soluzione, perché è semplicemente più concisa. Un'altra possibilità, se hai bisogno di una piccola animazione quando torni a tableView, è usare 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)
}
}
Ultimo ma non meno importante, se stai utilizzando un UITableViewController, puoi anche sfruttare la proprietà clearsSelectionOnViewWillAppear .
Per ottenere il comportamento descritto da Kendall Helmstetter Gelner nel suo commento, probabilmente non vorrai deselectRowAtIndexPath ma piuttosto la proprietà clearsSelectionOnViewWillAppear sul tuo controller. Forse questo è stato impostato su SÌ per caso?
Vedi il commento nel modello Apple predefinito per le nuove sottoclassi di UITableViewController:
- (void)viewDidLoad
{
[super viewDidLoad];
// Uncomment the following line to preserve selection between presentations.
// self.clearsSelectionOnViewWillAppear = NO;
}
Stavo riscontrando questo problema anche per la mia applicazione drill-down. Dopo che un viewcontroller, che chiamerò VC, ritorna dopo aver premuto un altro ViewController, la cella selezionata in VC è rimasta evidenziata. Nella mia app, avevo creato VC per gestire il secondo livello (su tre livelli) del mio drill-down.
Il problema nel mio caso è che VC era un UIViewController (che conteneva una vista che conteneva un TableView). Invece ho reso VC un UITableViewController (che conteneva un TableView). La classe UITableViewController gestisce automaticamente la deselezione della cella della tabella dopo il ritorno da un push. La seconda risposta al post " Problema con deselectRowAtIndexPath in tableView " fornisce una risposta più completa a questo problema.
Il problema non si è verificato per il viewcontroller di root perché quando ho creato l'app come "App basata sulla navigazione" in XCode, il risultante viewcontroller di root era già stato creato per sottoclassare UITableViewController.
Se nessuno di questi funziona per te, considera questa soluzione:
Utilizzare un svolgimento segue per chiamare:
@IBAction func unwind_ToTableVC (segue: UIStoryboardSegue) {
if let index = tableView.indexPathForSelectedRow {
tableView.deselectRowAtIndexPath(index, animated: true)
}
}
Perché farlo Soprattutto se hai problemi a far eseguire il codice deselezionato al momento giusto. Ho avuto problemi con il fatto che non funzionasse con ViewWillAppear, quindi lo svolgersi ha funzionato molto meglio.
passi:
Scrivi i seguenti svolgimenti (o incolla dall'alto) nel tuo 1 ° VC (quello con la tabella)
Vai al 2 ° VC. Tieni premuto il tasto Ctrl e trascina dal pulsante Annulla / Fine / Etc che stai utilizzando per eliminare quel VC e trascina sull'icona Esci in alto.
Seleziona lo svolgimento che segui creato nel passaggio 1
In bocca al lupo.
Sto usando CoreData, quindi il codice che ha funzionato per me era una combinazione di idee da varie risposte, in Swift:
override func viewDidAppear(_ animated: Bool) {
if let testSelected = yourTable.indexPathForSelectedRow {
yourTable.deselectRow(at: testSelected, animated: true)
}
super.viewDidAppear(true)
}
Ho avuto lo stesso problema da molto tempo, quindi nel caso in cui qualcun altro stia lottando:
Dai un'occhiata al tuo -tableView: cellForRowAtIndexPath:e vedi se stai creando celle o usando un 'identificatore di riutilizzo'. Se quest'ultimo, assicurati che la tua tabella in IB abbia una cella con quell'identificatore. Se non stai utilizzando un identificatore di riutilizzo, crea una nuova cella per ogni riga.
Ciò dovrebbe quindi dare alla tua tabella la "riga selezionata di dissolvenza" prevista sulla visualizzazione.
Utilizzare questo metodo nella classe UITableViewCell
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
// Just comment This line of code
// [super setSelected:selected animated:animated];
}
Per Swift 3: lo preferirei usare in viewDidDisappear
Definire:-
var selectedIndexPath = IndexPath()
In viewDidDisappear: -
override func viewDidDisappear(_ animated: Bool) {
yourTableView.deselectRow(at: selectedIndexPath, animated: true)
}
In didSelectRowAtIndexPath: -
func tableView(_ tableView: UITableView, didSelectRowAtIndexPath indexPath: IndexPath) {
selectedIndexPath = indexPath
}
se la cella rimane evidenziata dopo averla toccata, puoi chiamare il metodo UITabelView,
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
`[tableView deselectRowAtIndexPath:indexPath animated:YES];`
}
In alternativa, puoi utilizzare il seguente metodo e modificarlo in base alle tue esigenze,
// MARK: UITableViewDelegate
func tableView(tableView: UITableView, didHighlightRowAtIndexPath indexPath: NSIndexPath) {
if let cell = tableView.cellForRowAtIndexPath(indexPath) {
cell.backgroundColor = UIColor.greenColor()
}
}
func tableView(tableView: UITableView, didUnhighlightRowAtIndexPath indexPath: NSIndexPath) {
if let cell = tableView.cellForRowAtIndexPath(indexPath) {
cell.backgroundColor = UIColor.blackColor()
}
}
Xcode 10, Swift 4
Ho avuto lo stesso problema e ho scoperto di aver lasciato una chiamata vuota per viewWillAppear nella parte inferiore di tableViewController. Una volta rimossa la funzione di sostituzione vuota, la riga non è più rimasta evidenziata al ritorno alla vista tableView.
problema
override func viewWillAppear(_ animated: Bool) {
// need to remove this function if not being used.
}
la rimozione della funzione vuota ha risolto il mio problema.
deselectRowAtIndexPathnel mio viewDidAppear, se seleziona la riga fa apparire una nuova vista.