Come posso disabilitare la selezione UITableView?


1193

Quando si tocca una riga in a UITableView, la riga viene evidenziata e selezionata. È possibile disabilitarlo, quindi toccare una riga non fa nulla?


17
La domanda originale ha un titolo negativo. OP vuole principalmente disabilitare selection, e ovviamente highlightingviene disabilitato con quello. Molte risposte molto votate spiegano come disable selectione non affrontano la disabilitazione highlighting. Per disabilitare solo l'evidenziazione usa cell.selectionStyle = .Noneo vai astoryboard / cell / Selection = None
Andrej

Aggiorna il titolo o il post. Non ho capito bene. E sulla base di questa domanda, non ho idea di cosa debbano fare le risposte fornite.
Daniel Springer,

Risposte:


604

Per me, il seguente ha funzionato bene:

tableView.allowsSelection = false

Questo significa che didSelectRowAt#semplicemente non funzionerà. Vale a dire, toccare una fila del tavolo, come tale, non farà assolutamente nulla. (E quindi, ovviamente, non ci sarà mai un'animazione selezionata.)

(Nota che se, sulle celle, hai UIButtono qualsiasi altro controllo, ovviamente quei controlli funzioneranno comunque. Tutti i controlli che hai sulla cella della tabella, sono totalmente estranei alla capacità di UITableView di permetterti di "selezionare una riga" utilizzando didSelectRowAt#.)

Un altro punto da notare è che: questo non funziona quando UITableViewè in modalità di modifica. Per limitare la selezione di celle in modalità di modifica, utilizzare il codice come indicato di seguito:

tableView.allowsSelectionDuringEditing = false 

6
questo finalmente ha funzionato per me, ho provato ad usare cell.selectionStyle = UITableViewCellSelectionStyleNone; ma non ha funzionato. Una cosa da notare: dovrebbe essere: tableView.allowsSelection = NO; non falso.
tony.tc.leung,

6
Penso che questa sia l'opzione migliore. I pulsanti sulle celle sono attivi con questo, ma il testo non è attivo.
Fahim Parkar,

513
In che modo questa è la risposta accettata e ha così tanti voti positivi? Non risponde affatto alla domanda! Devi impostare la selectionStyleproprietà sulla cella: cell.selectionStyle = UITableViewCellSelectionStyle.Nonein Swift o cell.selectionStyle = UITableViewCellSelectionStyleNonein Objective-C.
nodebase,

5
Questo funziona per me in tableView.allowSelection = false
Swift

15
Ci sono alcuni modi per farlo a seconda di ciò che si desidera. Nessuno stile di selezione e nessuna selezione possono funzionare entrambi o entrambi possono fallire. Ecco un esempio Se si desidera selezionare la cella e si deve tableViewDidSelectRowAtIndexPathchiamare, cell.selectionStyle = .Nonesi desidera. Se non si desidera o non si desidera che venga chiamata quella funzione delegata (ovvero con un campo di testo in un tableViewCell) tableView.allowsSelection = falseva bene.
Made2k,

1964

Tutto quello che devi fare è impostare lo stile di selezione UITableViewCellsull'istanza usando:

Objective-C:

cell.selectionStyle = UITableViewCellSelectionStyleNone;

o

[cell setSelectionStyle:UITableViewCellSelectionStyleNone];

Swift 2:

cell.selectionStyle = UITableViewCellSelectionStyle.None

Swift 3 e 4.x:

cell.selectionStyle = .none

Inoltre, assicurarsi di non implementare -tableView:didSelectRowAtIndexPath:nella vista tabella delegato o di escludere esplicitamente le celle che non si desidera avere alcuna azione se lo si implementa.

Maggiori informazioni qui e qui


122
@Tony È una cattiva idea se hai un UITextField all'interno della cella.
Aniruddh Joshi,

73
@TonyMillion è anche una cattiva idea se si desidera utilizzare i controlli di modifica incorporati, come scorrere per eliminare. Se si imposta userInteractionEnabled su NO, il pulsante Elimina non risponde agli eventi di tocco dell'utente.
Carlos P,

47
tardi a questo thread, ma invece di userInteraction, utilizza cell.allowsSelection. Ciò interrompe i metodi di interazione della cella ma non blocca le normali cose del risponditore UIView.
Chris C,

4
L'impostazione di cell.userInteractionEnable = No non interromperà l'attivazione di didSelectRowAtIndexPath.
user4951

25
Voterò la risposta, ma solo per essere chiari, l'OP ha chiesto solo di disabilitare "l'evidenziazione", no per disabilitare l'intera interazione cellulare, quindi tutti questi commenti sono offtopici.
Frederic Yesid Peña Sánchez,

353

Poiché ho letto questo post di recente e mi ha aiutato, volevo pubblicare un'altra risposta per consolidare tutte le risposte (per i posteri).



Quindi, in realtà ci sono 5 risposte diverse a seconda della logica e / o del risultato desiderati:

1.Per disabilitare l'evidenziazione blu senza modificare altre interazioni della cella:

[cell setSelectionStyle:UITableViewCellSelectionStyleNone];

Lo uso quando ho un UIButton - o qualche altro controllo (i) - ospitato in un UITableViewCell e voglio che l'utente sia in grado di interagire con i controlli ma non con la cella stessa.

NOTA : come ha osservato Tony Million sopra, questo NON impediscetableView:didSelectRowAtIndexPath:. Lo aggiro con semplici istruzioni "if", il più delle volte test per la sezione ed evitando azioni per una particolare sezione.

Un altro modo in cui ho pensato di testare il tocco di una cella come questa è:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    // A case was selected, so push into the CaseDetailViewController
    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
    if (cell.selectionStyle != UITableViewCellSelectionStyleNone) {
        // Handle tap code here
    }
}



2.Per eseguire questa operazione per un'intera tabella, è possibile applicare la soluzione di cui sopra a ciascuna cella della tabella, ma è anche possibile:

[tableView setAllowsSelection:NO];

Nei miei test, questo consente comunque ai controlli all'interno UITableViewCelldi essere interattivi.


3.Per rendere una cella "sola lettura", puoi semplicemente fare questo:

[cell setUserInteractionEnabled:NO];



4.Per rendere l'intera tabella "sola lettura"

[tableView setUserInteractionEnabled:NO];



5. Per determinare al volo se evidenziare una cella (che in base a questa risposta include implicitamente la selezione), è possibile implementare il seguente UITableViewDelegatemetodo di protocollo:

- (BOOL)tableView:(UITableView *)tableView 
   shouldHighlightRowAtIndexPath:(NSIndexPath *)indexPath

3
Se carichi il design della cella da un pennino, la casella di controllo (in IB) funzionerà bene per il n. 3 (e sulle tabelle per il n. 4). Per # 4 vs # 2, la differenza è se i controlli all'interno della cella saranno interattivi?
lilbyrdie,

4
Sì. Se si desidera disabilitare la selezione ma consentire a UIButton, ecc ... di continuare a supportare l'interazione dell'utente, utilizzare # 2. Se vuoi una cella di sola lettura, usa # 4. Ovviamente, il motivo per cui dovresti avere qualsiasi cosa tranne UIViews o UILabels in una cella non interattiva è oltre me. Forse qualcuno vorrebbe disabilitare tutte le interazioni mentre si sta verificando qualcos'altro.
mbm29414

8
# 4 è un'idea terribile, farlo disabiliterà anche lo scorrimento nella vista tabella
simon

4
@simon In realtà, non è un'idea terribile; è un'opzione che può essere o meno una buona opzione a seconda delle circostanze. Inoltre, # 4 disabilita lo scorrimento UTENTE; potresti ancora implementare il tuo, se necessario. Sono d'accordo # 4 non è MOLTO utile, ma non è un'idea terribile.
mbm29414

3
Per completezza, potresti aggiungere un grido tableView:shouldHighlightRowAtIndexPath:, che è generalmente (non sempre) il mio approccio preferito.
Benjohn,

82

Riassumendo ciò che credo siano le risposte corrette basate sulla mia esperienza nell'implementazione di questo:

Se vuoi disabilitare la selezione solo per alcune celle, usa:

cell.userInteractionEnabled = NO;

Oltre a impedire la selezione, questo arresta anche tableView: didSelectRowAtIndexPath: chiamato per le celle che lo hanno impostato. (Il merito va a Tony Million per questa risposta, grazie!)

Se hai dei pulsanti nelle celle che devono essere cliccati, devi invece:

[cell setSelectionStyle:UITableViewCellSelectionStyleNone];

e devi anche ignorare qualsiasi clic sulla cella in - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath.

Se si desidera disabilitare la selezione per l'intera tabella, utilizzare:

tableView.allowsSelection = NO;

(Ringraziamo Paulo De Barros, grazie!)


cosa succede se abbiamo un pulsante nella nostra cella?
Umair Afzal

56

A partire da iOS 6.0, UITableViewDelegateha tableView:shouldHighlightRowAtIndexPath:. (Leggi a riguardo nella documentazione di iOS .)

Questo metodo consente di contrassegnare righe specifiche come non illuminabili (e implicitamente, non selezionabili) senza dover cambiare lo stile di selezione di una cella, fare confusione con la gestione degli eventi della cella con userInteractionEnabled = NOo altre tecniche documentate qui.


2
Mi sono imbattuto in questo thread e sono rimasto scioccato nel vedere tante altre risposte prima di questo. Questo è senza dubbio il modo corretto.
Beebcon,

2
Questa è davvero la risposta corretta e unica che dovrebbe essere considerata. Qualcos'altro che menziona userInteraction è completamente errato.
Mattyohe,

50

È inoltre possibile disabilitare la selezione di fila da Interface Builder per sé, scegliendo NoSelectiondalla selectionpossibilità (di proprietà UITableView) nel pannello impostazioni, come mostrato nell'immagine qui sotto

UITableView Inspector


2
La migliore soluzione IMHO
Itai Spector il

Uso spesso questa soluzione
Evsenev il


36

Nella tua UITableViewCell's XIB nel valore di attributo ispettore set di Selectiona None.

inserisci qui la descrizione dell'immagine


Questo è esattamente ciò di cui avevo bisogno. Volevo ancora la notifica didSelect ... ma senza l'indicazione visibile della selezione. Grazie!
Timothy Tripp,

Sono contento che abbia aiutato! :)
Zaid Pathan,

35

Se si desidera che la selezione lampeggi solo, non rimanga nello stato selezionato, è possibile chiamare, in

didSelectRowAtIndexPath

il seguente

[tableView deselectRowAtIndexPath:indexPath animated:YES];

quindi lampeggerà lo stato selezionato e ripristinerà.


3
Con questo approccio, la riga si evidenzia immediatamente e poi si attenua per mezzo secondo. Questo è il modo in cui Apple modella i loro menu Impostazioni, quindi mi sembra bello.
VinceFior,

34

Nel caso in cui qualcuno abbia bisogno di una risposta per Swift :

cell.selectionStyle = .None

1
possiamo anche usare questo cell.selectionStyle = UITableViewCellSelectionStyle.None
probabilmente

29

Questo è quello che uso, per cellForRowAtIndexPathscrivere questo codice .:

cell.selectionStyle = UITableViewCellSelectionStyleNone;

28

Dal UITableViewDelegateprotocollo è possibile utilizzare il metodo willSelectRowAtIndexPath e return nilse non si desidera selezionare la riga.

Allo stesso modo è possibile utilizzare il willDeselectRowAtIndexPathmetodo e return nilse non si desidera deselezionare la riga.


5
Non mi piace questo metodo perché mostra ancora la cella nel suo stato evidenziato fino al ritocco.
Kbanman,

2
è esattamente per questo che mi piace :-)
Joris Weimar

24

1- Tutto quello che devi fare è impostare lo stile di selezioneUITableViewCell sull'istanza usando:


Objective-C:

cell.selectionStyle = UITableViewCellSelectionStyleNone;

o

[cell setSelectionStyle:UITableViewCellSelectionStyleNone];


Swift 2:

cell.selectionStyle = UITableViewCellSelectionStyle.None


Swift 3:

cell.selectionStyle = .none


2 - Non implementare - tableView:didSelectRowAtIndexPath:nella vista tabella delegateo escludere esplicitamente le celle che non si desidera avere alcuna azione se lo si implementa.

3 - Inoltre, puoi anche farlo dallo storyboard. Fai clic sulla cella della vista tabella e nella finestra di ispezione degli attributi in Cella della vista tabella, modifica il menu a discesa accanto a Selezione su Nessuno.


4 - È possibile disabilitare l'evidenziazione della cella della tabella utilizzando il codice seguente in (iOS) Xcode 9, Swift 4.0

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {


        let cell = tableView.dequeueReusableCell(withIdentifier: "OpenTbCell") as! OpenTbCell
        cell.selectionStyle = .none
        return cell


}

20

Objective-C:

  1. Sotto lo snippet disabilita l'evidenziazione ma disabilita anche la chiamata a didSelectRowAtIndexPath. Quindi, se non stai implementando, didSelectRowAtIndexPathusa il metodo seguente. Questo dovrebbe essere aggiunto quando si crea la tabella. Questo funzionerà su pulsanti e UITextFieldall'interno della cella però.

    self.tableView.allowsSelection = NO;
  2. Sotto lo snippet disabilita l'evidenziazione e non disabilita la chiamata a didSelectRowAtIndexPath. Impostare lo stile di selezione della cella su Nessuno incellForRowAtIndexPath

    cell.selectionStyle = UITableViewCellSelectionStyleNone;
  3. Lo snippet di seguito disabilita tutto sulla cella. Questo disabiliterà l'interazione a buttons, textfields:

    self.tableView.userInteractionEnabled = false;

Swift:

Di seguito sono riportati gli Swiftequivalenti delle Objective-Csoluzioni precedenti :

  1. Sostituzione della prima soluzione

    self.tableView.allowsSelection = false
  2. Sostituzione della seconda soluzione

    cell?.selectionStyle = UITableViewCellSelectionStyle.None
  3. Sostituzione della terza soluzione

    self.tableView.userInteractionEnabled = false

19

Prova a digitare:

cell.selected = NO;

Deselezionerà la riga quando necessario.

In Swift3 ...

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    let r = indexPath.row
    print("clicked .. \(r)")
    tableView.cellForRow(at: indexPath)?.setSelected(false, animated: true)
}

14

Ho lottato con questo abbastanza abbondantemente, avendo un controllo nel mio UITableViewCellproibito l'uso della userInteractionEnabledproprietà. Ho una tabella statica a 3 celle per le impostazioni, 2 con le date, 1 con un interruttore on / off. Dopo aver giocato su Storyboard / IB sono riuscito a rendere non selezionabile quello in basso, ma quando lo tocchi la selezione da una delle prime righe scompare. Ecco un'immagine WIP delle mie impostazioni UITableView:

Impostazioni UITableView

Se tocchi la terza riga non succede nulla, la selezione rimarrà sulla seconda riga. La funzionalità è praticamente una copia della schermata di selezione dell'ora di aggiunta dell'app Calendario di Apple.

Il codice è sorprendentemente compatibile, fino a IOS2 = /:

- (NSIndexPath *)tableView: (UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    if (indexPath.row == 2) {
        return nil;
    }
    return indexPath;
}

Funziona insieme all'impostazione dello stile di selezione su nessuno, quindi la cella non sfarfalla su eventi di touchdown


11

Possiamo scrivere codice come

 cell.selectionStyle = UITableViewCellSelectionStyleNone;

ma quando abbiamo una cella personalizzata xib sopra la linea dare avvertimento in quel momento per

cella personalizzata xib

dobbiamo impostare lo stile di selezione Nessuno dal builder dell'interfaccia


11

Devi solo inserire questo codice in cellForRowAtIndexPath

Per disabilitare la proprietà di selezione della cella: (Mentre si tocca la cella).

cell.selectionStyle = UITableViewCellSelectionStyle.None

Grazie, ho un'immagine nella mia cella e un'etichetta sopra di essa. Ho impostato lo sfondo dell'etichetta, ma ogni volta che clicco lo sfondo scompare, questo lo ha risolto.
Darko,

10

prova questo

cell.selectionStyle = UITableViewCellSelectionStyleNone;

e

[cell setSelectionStyle:UITableViewCellSelectionStyleNone];

e puoi anche impostare lo stile di selezione usando interfacebuilder.


10

Sto usando questo, che funziona per me.

cell?.selectionStyle = UITableViewCellSelectionStyle.None

7

Mentre questa è la soluzione migliore e più semplice per evitare che una riga mostri l'evidenziazione durante la selezione

cell.selectionStyle = UITableViewCellSelectionStyleNone;

Vorrei anche suggerire che a volte è utile mostrare brevemente che la riga è stata selezionata e quindi disattivarla. Questo avvisa gli utenti con una conferma di ciò che intendevano selezionare:

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

7

Disattiva direttamente l'evidenziazione di TableViewCell nello storyboard

inserisci qui la descrizione dell'immagine


6

Per disabilitare l'evidenziazione di UItableviewcell

cell.selectionStyle = UITableViewCellSelectionStyleNone;

E non dovrebbe consentire all'utente di interagire con la cella.

cell.userInteractionEnabled = NO;

6

È inoltre possibile impostare il colore di sfondo su Cancella per ottenere lo stesso effetto UITableViewCellSelectionStyleNone, nel caso in cui non si desideri / non si possa usare UITableViewCellSelectionStyleNone.

Utilizzeresti un codice come il seguente:

UIView *backgroundColorView = [[UIView alloc] init];
backgroundColorView.backgroundColor = [UIColor clearColor];
backgroundColorView.layer.masksToBounds = YES;
[cell setSelectedBackgroundView: backgroundColorView];

Ciò potrebbe peggiorare le tue prestazioni quando aggiungi una vista colorata in più a ogni cella.


6

Puoi usare :

cell.selectionStyle = UITableViewCellSelectionStyleNone;

nella cella per la riga nel metodo del percorso dell'indice di UITableView.

Inoltre puoi usare:

[tableView deselectRowAtIndexPath:indexPath animated:NO];

nel tableview didselectrowatindexpath method.


Ora è cell.selectionStyle = UITableViewCellSelectionStyle.nonein Swift 3.
Dan

5

Puoi usare questo

cell.selectionStyle = UITableViewCellSelectionStyleNone;

5

Puoi usare ....

[cell setSelectionStyle:UITableViewCellSelectionStyleNone];


5
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
[cell setSelected:NO animated:NO];
[cell setHighlighted:NO animated:NO];

Buona codifica !!!


5

Puoi anche farlo dallo storyboard. Fai clic sulla cella della vista tabella e nella finestra di ispezione degli attributi in Cella della vista tabella, modifica il menu a discesa accanto a Selezione su Nessuno.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.