2012-03-22 27 views
21

Ho creato un nuovo progetto (Xcode 4, applicazione Master-Detail) solo per vedere se sto facendo qualcosa di sbagliato, ma ho ancora lo stesso problema. Voglio chiamare -reloadData quando l'utente deseleziona una cella, quindi questo è il mio codice:Perché non viene chiamato -didDeselectRowAtIndexPath?

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    [tableView deselectRowAtIndexPath:indexPath animated:YES]; 
    NSLog(@"%s", __PRETTY_FUNCTION__); 
} 

-(void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath { 
    NSLog(@"%s", __PRETTY_FUNCTION__); 
    [tableView reloadData]; 
} 

-(NSIndexPath *)tableView:(UITableView *)tableView willDeselectRowAtIndexPath:(NSIndexPath *)indexPath { 
    NSLog(@"%s", __PRETTY_FUNCTION__); 
    return indexPath; 
} 

Il problema è che didDeselectRowAtIndexPath e willDeselectRowAtIndexPath non sembrano essere chiamato. È questo il comportamento previsto? Documenti per lo stato tableView:didDeselectRowAtIndexPath:

Indica al delegato che la riga specificata è ora deselezionata.

quindi immagino che dovrebbe funzionare come pensavo.

+0

Avete impostato correttamente il delegato per l'UITableView? –

+0

hai specificato le tabelle delegate? e hai permesso agli utenti di selezionare le celle? –

+0

Sì e sì. La selezione funziona come dovrebbe, la de-selezione è il problema .. – phi

risposta

17

la documentazione di tableView:willDeselectRowAtIndexPath: dice anche che

Questo metodo viene chiamato solo se v'è una selezione esistente quando l'utente tenta di selezionare una riga diversa. Al delegato viene inviato questo metodo per la riga selezionata in precedenza. È possibile utilizzare UITableViewCellSelectionStyleNone per disabilitare l'aspetto dell'evidenziazione cella sul touch-down.

Non ha funzionato per noi quando ho usato UITableViewCellSelectionStyleNone.

+0

Ma questo è per 'willDeselectRowAtIndexPath', non per' didDeselectRowAtIndexPath' giusto ?? Potrebbe essere che entrambi vengono lanciati solo dopo che viene selezionata una cella diversa? – phi

+0

Questo è per entrambi, selezionare [UITableViewDelegate Protocol Reference] (https://developer.apple.com/library/ios/documentation/UIKit/Reference/UITableViewDelegate_Protocol/) – beryllium

+0

Ok, ma se ci dimentichiamo di 'willDeselectRowAtIndexPath', sembra che non sto facendo qualcosa di sbagliato, e che 'didDeselectRowAtIndexPath' non sta funzionando nel modo in cui lo voglio, giusto? – phi

46

Se si chiama deselectRowAtIndexPath:animated:, i metodi di delegato tableView:willDeselectRowAtIndexPath: e il messaggio tableView:didDeselectRowAtIndexPath: non vengono inviati.

+4

Questa dovrebbe essere la risposta accettata. – tasomaniac

+0

E il riconoscitore di gesti?Verrà eseguito se usiamo 'deselectRowAtIndexPath: animated:'? – Ron

9

Un altro capriccio che ho trovato - in IOS 5.1, in ogni caso - è che se si chiama reloadData sul tavolo, non si otterrà didDeselectRowAtIndexPath per le righe selezionate. Nel mio caso, aggiusto leggermente il layout della cella a seconda che sia selezionato o meno, quindi ho dovuto farlo manualmente prima di ricaricare i dati della tabella.

+0

Hai ragione. 'reloadData' rende tableView" dimentica "le righe selezionate. Tuttavia c'è una soluzione rapida per questo: basta ricaricare righe specifiche chiamando 'reloadRowsAtIndexPaths: withAnimation:' – Philip007

0

Impostare allowsMultipleSelection per quella Tableview a TRUE

self.tableView.allowsMultipleSelection = YES; 
0

Penso che sia solo semplice errore! Perché non si utilizza seguente:

[self.tableView deselectRowAtIndexPath:indexPath animated:YES]; 

Invece di usare solo "tableView" in quella linea?
Immagino, e sono sicuro che quella linea ti darebbe la soluzione!
spero che questo ti abbia aiutato, se hai guardato indietro alla tua vecchia domanda !!!
Complimenti! :)

+0

Non penso che questo sia il problema, tableView si riferisce comunque a self.tableView. Provalo, imparerai qualcosa. – phi

+0

:? ok, scusate se ho ingannato allora! Vorrei provare e pubblicare i risultati come commento qui! Grazie per il consiglio! –

3

So che questa è una vecchia domanda, ma mi sono imbattuto nello stesso problema.

Se si utilizza

[tableView reloadData] 

Poi I dati tabella viene ricaricata e nessuna riga è selezionata dietro le quinte - che significa

solo

didSelectRowAtIndexPath 

viene mai chiamato. Spero che questo aiuti qualcuno che si imbatte in questo problema.

2

Un modo pulito per risolvere questo problema è quello di effettuare le seguenti operazioni:

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 
    let cell = tableView.dequeueReusableCellWithIdentifier("myCell", forIndexPath: indexPath) 
    // Do your cell setup work here... 

    //If your cell should be selected... 
    if cellShouldBeSelected { 
     tableView.selectRowAtIndexPath(indexPath, animated: false, scrollPosition: UITableViewScrollPosition.None) 
    } 

    return cell 
} 

Questo risolve questo problema intero di una cella non risponde ad essere deselezionato dopo una chiamata tableView.reloadData() succede.

+0

Non mi piace particolarmente Swift, ma il tuo consiglio _really_ mi ha aiutato, grazie mille! –

0

Quando una cella viene selezionata per la prima volta, non viene chiamato il metodo -[UITableViewDelegate tableView:didDeselectRowAtIndexPath:], ma -[UITableViewDelegate tableView:didSelectRowAtIndexPath:]. Subito dopo aver selezionato un'altra cella, lo didDeselectRowAtIndexPath viene chiamato subito dopo lo didSelectRowAtIndexPath.

Questo è OK.

Ma se si deve mostrare una cella come selezionato agli inizi, (e.q. utilizzando UITableViewCellAccessoryCheckmark), poi, dopo aver selezionato un'altra cella probabilmente si desidera il metodo didDeselectRowAtIndexPath viene chiamato per la prima volta, per deselezionare la cella precedente.

La soluzione!

dovete chiamare il -[UITableView selectRowAtIndexPath:animated:scrollPosition:] nella -[UITableViewDataSource tableView:cellForRowAtIndexPath:] per notificare che una cellula ricercato è già selezionata.

Objective-C

#pragma mark - UITableViewDelegate 

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath]; 
    cell.accessoryType = UITableViewCellAccessoryCheckmark; 
    // saving the current selected row 
    SelectedRow = indexPath.row; 
} 

- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath]; 
    cell.accessoryType = UITableViewCellAccessoryNone; 
} 

#pragma mark - UITableViewDataSource 

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"]; 

    if (!cell) { 
     cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"cell"]; 
    } 

    // preventing selection style 
    cell.selectionStyle = UITableViewCellSelectionStyleNone; 

    cell.textLabel.text = "Some text"; 

    if (indexPath.row == SelectedRow) { 
     cell.accessoryType = UITableViewCellAccessoryCheckmark; 
     // just wanted to make it selected, but it also can scroll to the selected position 
     [tableView selectRowAtIndexPath:indexPath animated:NO scrollPosition:UITableViewScrollPositionNone]; 
    } 

    return cell; 
} 

Swift 3,1

// MARK: - UITableViewDelegate 

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { 
    let cell = tableView.cellForRow(at: indexPath)! 
    cell.accessoryType = UITableViewCellAccessoryType.checkmark 
    selectedRow = indexPath.row 
} 

override func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) { 
    let cell = tableView.cellForRow(at: indexPath)! 
    cell.accessoryType = UITableViewCellAccessoryType.none 
} 

// MARK: - UITableViewDataSource 

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 
    let cell = UITableViewCell(style: UITableViewCellStyle.default, reuseIdentifier: "cell") 

    // preventing selection style 
    cell.selectionStyle = UITableViewCellSelectionStyle.none 

    cell.textLabel?.text = "some text" 

    if (indexPath.row == selectedRow) { 
     cell.accessoryType = UITableViewCellAccessoryType.checkmark 
     // just wanted to make it selected, but it also can scroll to the selected position 
     tableView.selectRow(at: indexPath, animated: false, scrollPosition: UITableViewScrollPosition.none) 
    } 

    return cell 
} 
Problemi correlati