2010-05-10 16 views
54

Quando si spinge una vista dopo che un utente ha selezionato una riga UITableView, la riga diventa evidenziata in blu, quindi viene visualizzata la nuova vista. Va bene. Ma quando ritorno 'indietro' la riga è ancora evidenziata in blu. Ecco il mio codice didSelectRowAtIndexPath.Selezionato UItableViewCell che rimane blu quando selezionato

- (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; 
} 

Cosa sto sbagliando?

risposta

170

Come indicato nelle risposte precedenti, è necessario deselezionare esplicitamente la riga. Hai due opzioni su come farlo. Il primo, è per deselezionare riga immediatamente dopo la selezione:

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

che funzionano bene, ma c'è un'alternativa, e la sua l'approccio adottato dal UITableViewController che deve lasciare la riga selezionata quindi deselezionate quando la la visualizzazione riappare (dopo che il controller che stai spingendo viene estratto dalla pila).

Questo ha il leggero vantaggio che l'utente vede un'anteprima della loro precedente selezione al loro ritorno in modo da poter vedere ciò che avevano precedentemente selezionato.

Per implementare questo, basta eseguire l'override viewWillAppear:

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

Come ho detto, questo è ciò che il default di attuazione del UITableViewController s' viewWillAppear: lo fa se si utilizza UITableViewController e non vedere questo comportamento, è necessario verificare che si stia chiamando l'implementazione super nella propria classe viewDidAppear:.

Aggiornamento (30 ott 2013): beh, questa è una risposta popolare! Come Ben giustamente fa notare nei commenti, UITableViewController fa questo in viewWillAppear: non viewDidAppear: - questo è il momento giusto. Inoltre, si attiva e disattiva questo comportamento utilizzando la proprietà clearsSelectionOnViewWillAppear di UITableViewController. Ho modificato la mia risposta sopra per riflettere questo.

+0

veramente bello. Grazie per questo. – ToddB

+0

@Luke Redpath awesome ... Grazie – death7eater

+1

Questa è un'ottima risposta, ma suggerirei di posizionarla in 'viewWillAppear' per simulare accuratamente i tempi della deselezione di UITableViewController. –

7

è necessario deselezionare esso:

[tableView deselectRowAtIndexPath:indexPath animated:YES];

3

Hai solo bisogno di chiamare [tableView deselectRowAtIndexPath: indexPath animato: SI].

1

Il comportamento predefinito di UITableViewController deseleziona la riga quando l'utente torna dalla visualizzazione di dettaglio. La risposta fornita da Luke va bene, ma voglio indicarne il motivo:

1- Se hai il tuo UITableViewController come quando lo hai creato da zero, avrai tutti i comportamenti predefiniti.

2- Se nella situazione 1 si aggiunge -viewWillAppear o -viewDidAppear, verrà sovrascritto il comportamento standard. Se vuoi che la riga deselezioni al momento del ritorno, devi dire esplicitamente allo super che desideri deselezionare la riga come sempre!Per raggiungere questo obiettivo, come dice Luca, è necessario chiamare [super viewWillAppear:animated] o [super viewDidAppear:animated] come questo:

-(void)viewWillAppear:(BOOL)animated { 

    [super viewWillAppear:animated]; 

    // Here goes all of your stuff 
} 
0

Un'altra soluzione è quella di chiamare reloadData di UITableView in viewWillAppear

+0

Sì, ma penso che sia considerato una buona forma per non cospargere il proprio codice con le chiamate a reloadData. C'è spesso una soluzione più performante. –

4

Se il controller si basa su UITableViewController, si ottiene questa caratteristica per gratuito. Ma spesso ho finito con l'uso di UIViewController con no. di altri controlli, oltre a UITableView, in questo caso, si dovrebbe ignorare la vostra viewWillAppear a

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

UITableViewController ha una proprietà BOOL chiamato clearsSelectionOnViewWillAppear che fa esattamente quello che vuoi.

Per impostazione predefinita è impostato su YES, ma ho notato che è possibile (talvolta accidentalmente) disabilitare questa proprietà implementando il proprio metodo viewWillAppear:. Penso che questo sia dovuto al fatto che la deselezione avviene durante lo [UITableViewController viewWillAppear:] che potrebbe non essere mai chiamato se lo si sovrascrive.

La soluzione è semplice, quindi. Basta chiamare la versione Super di viewWillAppear: qualche parte nella tua versione di tale metodo:

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

Apple consiglia sempre chiamare la versione super di qualsiasi della vista {DID, Will} {A, Disa} metodi ppear se li si ignora.

Riferimenti

Problemi correlati