Comment puis-je désactiver la sélection UITableView?

1193

Lorsque vous appuyez sur une ligne dans a UITableView, la ligne est mise en surbrillance et sélectionnée. Est-il possible de désactiver cela afin que le fait de toucher une ligne ne fasse rien?

DavidM
la source
17
La question d'origine a un mauvais titre. OP veut principalement désactiver selection, et bien sûr highlightingest désactivé avec cela. De nombreuses réponses à vote élevé expliquent comment disable selectionet ne traitent pas la désactivation highlighting. Pour désactiver uniquement la mise en surbrillance, utilisez cell.selectionStyle = .Noneou accédez àstoryboard / cell / Selection = None
Andrej
Veuillez mettre à jour le titre ou le message. Je suis confus. Et sur la base de cette question, je n'ai aucune idée de ce que les réponses fournies sont censées faire.
Daniel Springer

Réponses:

604

Pour moi, les choses suivantes ont bien fonctionné:

tableView.allowsSelection = false

Cela signifie didSelectRowAt#tout simplement ne fonctionnera pas. Autrement dit, toucher une ligne de la table, en tant que telle, ne fera absolument rien. (Et donc, évidemment, il n'y aura jamais d'animation sélectionnée.)

(Notez que si, sur les cellules, vous avez UIButtonou tout autre contrôle, bien sûr, ces contrôles fonctionneront toujours. Tous les contrôles que vous avez sur la cellule du tableau sont totalement indépendants de la capacité d'UITableView de vous permettre de "sélectionner une ligne" en utilisant didSelectRowAt#.)

Un autre point à noter est le suivant: cela ne fonctionne pas lorsque le UITableViewest en mode édition. Pour restreindre la sélection de cellules en mode édition, utilisez le code ci-dessous:

tableView.allowsSelectionDuringEditing = false 
Let's_Create
la source
6
cela a finalement fonctionné pour moi, j'ai essayé d'utiliser cell.selectionStyle = UITableViewCellSelectionStyleNone; mais ça n'a pas marché. Une chose à noter: elle devrait être: tableView.allowsSelection = NO; pas faux.
tony.tc.leung
6
Je pense que c'est la meilleure option. Les boutons sur les cellules sont actifs avec cela, mais le texte n'est pas actif.
Fahim Parkar
513
Comment est-ce la réponse acceptée et a-t-il autant de votes positifs? Cela ne répond pas du tout à la question! Vous devez définir la selectionStylepropriété sur la cellule: cell.selectionStyle = UITableViewCellSelectionStyle.Nonedans Swift ou cell.selectionStyle = UITableViewCellSelectionStyleNonedans Objective-C.
nodebase
5
Cela fonctionne pour moi dans Swift 2.tableView.allowSelection = false
Khanad
15
Il existe plusieurs façons de le faire en fonction de ce qui est souhaité. Aucun style de sélection et aucune sélection ne peuvent tous deux fonctionner ou échouer. Voici un exemple. Si vous souhaitez sélectionner la cellule et la tableViewDidSelectRowAtIndexPathfaire appeler, cell.selectionStyle = .Noneest souhaité. Si vous ne voulez pas ou que vous ne voulez pas que cette fonction déléguée soit appelée (c'est-à-dire avoir un champ de texte dans une tableViewCell), le réglage tableView.allowsSelection = falseest très bien.
Made2k
1964

Il vous suffit de définir le style de sélection sur l' UITableViewCellinstance en utilisant soit:

Objectif c:

cell.selectionStyle = UITableViewCellSelectionStyleNone;

ou

[cell setSelectionStyle:UITableViewCellSelectionStyleNone];

Swift 2:

cell.selectionStyle = UITableViewCellSelectionStyle.None

Swift 3 et 4.x:

cell.selectionStyle = .none

En outre, assurez-vous de ne pas implémenter -tableView:didSelectRowAtIndexPath:dans votre délégué de vue tabulaire ou d'exclure explicitement les cellules que vous ne souhaitez pas avoir d'action si vous l'implémentez.

Plus d'infos ici et ici

Martin Gordon
la source
122
@Tony C'est une mauvaise idée si vous avez un UITextField à l'intérieur de la cellule.
Aniruddh Joshi
73
@TonyMillion c'est aussi une mauvaise idée si vous souhaitez utiliser des contrôles d'édition intégrés, tels que glisser pour supprimer. Si vous définissez userInteractionEnabled sur NO, le bouton Supprimer ne répond pas aux événements tactiles de l'utilisateur.
Carlos P
47
tard dans ce fil, mais au lieu de userInteraction, utilisez cell.allowsSelection. Cela arrête les méthodes d'interaction de la cellule mais ne bloque pas les éléments de réponse UIView habituels.
Chris C
4
La définition de cell.userInteractionEnable = No n'arrêtera pas de déclencher un didSelectRowAtIndexPath.
user4951
25
Je voterai la réponse, mais juste pour être clair, l'OP n'a demandé que la désactivation de la "mise en évidence", non pour désactiver l'interaction de la cellule entière, donc tous ces commentaires sont hors sujet.
Frédéric Yesid Peña Sánchez du
353

Parce que j'ai lu ce post récemment et que cela m'a aidé, je voulais poster une autre réponse pour consolider toutes les réponses (pour la postérité).



Donc, il y a en fait 5 réponses différentes selon la logique et / ou le résultat souhaité:

Pour désactiver la surbrillance bleue sans modifier aucune autre interaction de la cellule:

[cell setSelectionStyle:UITableViewCellSelectionStyleNone];

J'utilise ceci quand j'ai un UIButton - ou un autre contrôle (s) - hébergé dans un UITableViewCell et je veux que l'utilisateur puisse interagir avec les contrôles mais pas la cellule elle-même.

REMARQUE : Comme Tony Million l'a noté ci-dessus, cela n'empêche PAS tableView:didSelectRowAtIndexPath:. Je contourne cela par de simples instructions "if", le plus souvent en testant la section et en évitant l'action pour une section particulière.

Une autre façon dont j'ai pensé à tester le taraudage d'une cellule comme celle-ci est:

- (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.Pour ce faire pour un tableau entier, vous pouvez appliquer la solution ci-dessus à chaque cellule du tableau, mais vous pouvez également le faire:

[tableView setAllowsSelection:NO];

Dans mes tests, cela permet toujours aux contrôles internes UITableViewCelld'être interactifs.


3.Pour rendre une cellule "en lecture seule", vous pouvez simplement faire ceci:

[cell setUserInteractionEnabled:NO];



4.Pour rendre une table entière "en lecture seule"

[tableView setUserInteractionEnabled:NO];



5.Pour déterminer à la volée s'il faut mettre en évidence une cellule (qui, selon cette réponse, inclut implicitement la sélection), vous pouvez implémenter la UITableViewDelegateméthode de protocole suivante :

- (BOOL)tableView:(UITableView *)tableView 
   shouldHighlightRowAtIndexPath:(NSIndexPath *)indexPath
mbm29414
la source
3
Si vous chargez la conception de cellule à partir d'une pointe, la case à cocher (dans IB) fonctionnera très bien pour # 3 (et sur les tables pour # 4). Pour # 4 vs # 2, est-ce que les contrôles à l'intérieur de la cellule seront interactifs ou non?
lilbyrdie
4
Oui. Si vous souhaitez désactiver la sélection mais autoriser les boutons UIB, etc ... pour continuer à prendre en charge l'interaction utilisateur, utilisez # 2. Si vous voulez une cellule complètement en lecture seule, utilisez # 4. Bien sûr, pourquoi vous auriez autre chose que des UIViews ou des UILabels dans une cellule non interactive me dépasse. Peut-être que quelqu'un voudrait désactiver toutes les interactions pendant que quelque chose d'autre se produit.
mbm29414
8
# 4 est une idée terrible, cela désactivera également le défilement dans la vue de la table
Simon
4
@simon En fait, ce n'est pas une idée terrible; c'est une option qui peut ou non être une bonne option selon votre situation. En outre, # 4 désactive le défilement USER; vous pouvez toujours implémenter le vôtre, si nécessaire. Je suis d'accord # 4 n'est pas beaucoup utile, mais ce n'est pas une idée terrible.
mbm29414
3
Pour être complet, pourriez-vous ajouter un cri pour tableView:shouldHighlightRowAtIndexPath:, qui est généralement (pas toujours) mon approche préférée.
Benjohn
82

Pour résumer ce que je pense être les bonnes réponses en fonction de ma propre expérience dans la mise en œuvre de ceci:

Si vous souhaitez désactiver la sélection pour seulement certaines cellules, utilisez:

cell.userInteractionEnabled = NO;

En plus d'empêcher la sélection, cela arrête également tableView: didSelectRowAtIndexPath: appelé pour les cellules qui l'ont défini. (Nous remercions Tony Million pour cette réponse, merci!)

Si vous avez des boutons dans vos cellules sur lesquels vous devez cliquer, vous devez plutôt:

[cell setSelectionStyle:UITableViewCellSelectionStyleNone];

et vous devez également ignorer tous les clics sur la cellule - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath.

Si vous souhaitez désactiver la sélection pour l'ensemble du tableau, utilisez:

tableView.allowsSelection = NO;

(Merci à Paulo De Barros, merci!)

JosephH
la source
Et si nous avons un bouton dans notre cellule?
Umair Afzal
56

Depuis iOS 6.0, UITableViewDelegatea tableView:shouldHighlightRowAtIndexPath:. (Lisez à ce sujet dans la documentation iOS .)

Cette méthode vous permet de marquer des lignes spécifiques comme non surlignables (et implicitement, non sélectionnables) sans avoir à changer le style de sélection d'une cellule, à jouer avec la gestion des événements de la cellule avec userInteractionEnabled = NO, ou toute autre technique documentée ici.

cbowns
la source
2
Je suis tombé sur ce fil et j'ai été choqué de voir tant d'autres réponses avant celle-ci. C'est sans aucun doute la bonne façon.
beebcon
2
C'est en effet la seule et bonne réponse à prendre en compte. Tout autre élément mentionnant userInteraction est complètement incorrect.
mattyohe
50

Vous pouvez également désactiver la sélection de ligne à partir du générateur d'interface lui-même en choisissant NoSelectionparmi l' selectionoption (des propriétés UITableView) dans le volet d'inspection, comme indiqué dans l'image ci-dessous

Inspecteur UITableView

vignesh kumar
la source
2
Meilleure solution à mon humble avis
Itai Spector
J'utilise souvent cette solution
Evsenev
46

SOLUTION FIXE POUR SWIFT 3

cell.selectionStyle = .none
MANISH PATHAK
la source
36

Dans votre UITableViewCell« s XIB de la valeur de consigne d'attributs de l' inspecteur Selectionà None.

entrez la description de l'image ici

Zaid Pathan
la source
C'est exactement ce dont j'avais besoin. Je voulais toujours la notification didSelect ... mais sans indication visible de sélection. Merci!
Timothy Tripp
Heureux que cela ait aidé! :)
Zaid Pathan
35

Si vous souhaitez que la sélection ne clignote que sans rester dans l’état sélectionné, vous pouvez appeler,

didSelectRowAtIndexPath

le suivant

[tableView deselectRowAtIndexPath:indexPath animated:YES];

il fera donc clignoter l'état sélectionné et reviendra.

Chris Fox
la source
3
Avec cette approche, la ligne se met instantanément en surbrillance puis s'estompe sur une demi-seconde. C'est ainsi qu'Apple stylise ses menus Paramètres, donc ça me semble bien.
VinceFior
34

Au cas où quelqu'un aurait besoin d'une réponse pour Swift :

cell.selectionStyle = .None
Aks
la source
1
nous pouvons également utiliser ce cell.selectionStyle = UITableViewCellSelectionStyle.None
bably
29

Voici ce que j'utilise, en cellForRowAtIndexPathécrivant ce code:

cell.selectionStyle = UITableViewCellSelectionStyleNone;
Ahsan Ebrahim
la source
28

Depuis le UITableViewDelegateprotocole, vous pouvez utiliser la méthode willSelectRowAtIndexPath et return nilsi vous ne voulez pas que la ligne soit sélectionnée.

De la même manière, vous pouvez utiliser la willDeselectRowAtIndexPathméthode et return nilsi vous ne souhaitez pas que la ligne soit désélectionnée.

user41806
la source
5
Je n'aime pas cette méthode car elle montre toujours la cellule dans son état en surbrillance jusqu'à la retouche.
kbanman
2
c'est exactement pourquoi je l'aime :-)
Joris Weimar
24

1- Tout ce que vous avez à faire est de définir le style de sélection sur l'UITableViewCell instance en utilisant soit:


Objectif c:

cell.selectionStyle = UITableViewCellSelectionStyleNone;

ou

[cell setSelectionStyle:UITableViewCellSelectionStyleNone];


Swift 2:

cell.selectionStyle = UITableViewCellSelectionStyle.None


Swift 3:

cell.selectionStyle = .none


2 - Ne pas implémenter - tableView:didSelectRowAtIndexPath:dans votre vue tableau delegateou exclure explicitement les cellules que vous ne souhaitez pas avoir d'action si vous l'implémentez.

3 - De plus, vous pouvez également le faire à partir du storyboard. Cliquez sur la cellule de vue tableau et dans l'inspecteur d'attributs sous Cellule vue tableau, modifiez la liste déroulante en regard de Sélection sur Aucun.


4 - Vous pouvez désactiver la surbrillance des cellules du tableau à l'aide du code ci-dessous dans (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


}
parvind
la source
20

Objectif c:

  1. Au-dessous de l'extrait, désactivez la mise en surbrillance, mais désactivez également l'appel à didSelectRowAtIndexPath. Donc, si vous n'implémentez pas, didSelectRowAtIndexPathutilisez la méthode ci-dessous. Cela doit être ajouté lorsque vous créez la table. Cela fonctionnera cependant sur les boutons et UITextFieldà l'intérieur de la cellule.

    self.tableView.allowsSelection = NO;
  2. L'extrait ci-dessous désactive la mise en surbrillance et ne désactive pas l'appel à didSelectRowAtIndexPath. Définissez le style de sélection de la cellule sur Aucun danscellForRowAtIndexPath

    cell.selectionStyle = UITableViewCellSelectionStyleNone;
  3. L'extrait ci-dessous désactive tout sur la cellule. Cela désactive l'interaction buttons, textfields:

    self.tableView.userInteractionEnabled = false;

Rapide:

Voici l' Swiftéquivalent des Objective-Csolutions ci-dessus :

  1. Remplacement de la première solution

    self.tableView.allowsSelection = false
  2. Remplacement de la deuxième solution

    cell?.selectionStyle = UITableViewCellSelectionStyle.None
  3. Remplacement de la troisième solution

    self.tableView.userInteractionEnabled = false
Arun Gupta
la source
19

Essayez de taper:

cell.selected = NO;

Il désélectionnera votre ligne en cas de besoin.

Dans Swift3 ...

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

Je me bats avec cela assez abondamment aussi, ayant un contrôle sur mon UITableViewCellinterdiction d'utiliser des userInteractionEnabledbiens. J'ai un tableau statique à 3 cellules pour les paramètres, 2 avec les dates, 1 avec un interrupteur marche / arrêt. Après avoir joué dans Storyboard / IB, j'ai réussi à rendre celui du bas non sélectionnable, mais lorsque vous appuyez dessus, la sélection de l'une des lignes supérieures disparaît. Voici une image WIP de mes paramètres UITableView:

Paramètres UITableView

Si vous appuyez sur la 3e ligne, rien ne se passe du tout, la sélection restera sur la deuxième ligne. La fonctionnalité est pratiquement une copie de l'écran de sélection d'ajout d'événement de l'application Calendrier d'Apple.

Le code est étonnamment compatible, jusqu'à IOS2 = /:

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

Cela fonctionne en conjonction avec la définition du style de sélection sur aucun, de sorte que la cellule ne scintille pas lors des événements de toucher

Yarek T
la source
11

Nous pouvons écrire du code comme

 cell.selectionStyle = UITableViewCellSelectionStyleNone;

mais lorsque nous avons une cellule personnalisée xib au-dessus de la ligne, donnez un avertissement à ce moment-là pour

cellule personnalisée xib

nous devons définir le style de sélection Aucun dans le générateur d'interface

iDhaval
la source
11

Il vous suffit de mettre ce code dans cellForRowAtIndexPath

Pour désactiver la propriété de sélection de la cellule: (tout en appuyant sur la cellule).

cell.selectionStyle = UITableViewCellSelectionStyle.None
Gaurav Patel
la source
Merci, j'ai une image dans ma cellule et une étiquette dessus. J'ai défini l'arrière-plan de l'étiquette, mais chaque fois que je cliquais sur l'arrière-plan disparaissait, cela le résolvait.
Darko
10

essaye ça

cell.selectionStyle = UITableViewCellSelectionStyleNone;

et

[cell setSelectionStyle:UITableViewCellSelectionStyleNone];

et vous pouvez également définir le style de sélection en utilisant interfacebuilder.

v_1
la source
10

J'utilise ceci, qui fonctionne pour moi.

cell?.selectionStyle = UITableViewCellSelectionStyle.None
priyanka gautam
la source
7

Bien que ce soit la solution la meilleure et la plus simple pour empêcher une ligne d'afficher la surbrillance lors de la sélection

cell.selectionStyle = UITableViewCellSelectionStyleNone;

Je voudrais également suggérer qu'il est parfois utile de montrer brièvement que la ligne a été sélectionnée, puis de la désactiver. Cela alerte les utilisateurs avec une confirmation de ce qu'ils avaient l'intention de sélectionner:

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

Désactivez directement la mise en surbrillance de TableViewCell dans le storyboard

entrez la description de l'image ici

Kamani Jasmin
la source
6

Pour désactiver la mise en évidence de l'UItableviewcell

cell.selectionStyle = UITableViewCellSelectionStyleNone;

Et ne doit pas permettre à l'utilisateur d'interagir avec la cellule.

cell.userInteractionEnabled = NO;
Sharme
la source
6

Vous pouvez également définir la couleur d'arrière-plan sur Effacer pour obtenir le même effet que UITableViewCellSelectionStyleNonedans le cas où vous ne souhaitez pas / ne pouvez pas utiliser UITableViewCellSelectionStyleNone.

Vous utiliseriez du code comme celui-ci:

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

Cela peut dégrader vos performances lorsque vous ajoutez une vue colorée supplémentaire à chaque cellule.

virindh
la source
6

Vous pouvez utiliser :

cell.selectionStyle = UITableViewCellSelectionStyleNone;

dans la cellule de la ligne sur la méthode du chemin d'index de votre UITableView.

Vous pouvez également utiliser:

[tableView deselectRowAtIndexPath:indexPath animated:NO];

dans la méthode tableview didselectrowatindexpath.

Annu
la source
C'est maintenant cell.selectionStyle = UITableViewCellSelectionStyle.nonedans Swift 3.
Dan
5

Vous pouvez utiliser ceci

cell.selectionStyle = UITableViewCellSelectionStyleNone;
iEinstein
la source
5

Vous pouvez utiliser ....

[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
Mak083
la source
5
cell.selectionStyle = UITableViewCellSelectionStyleNone;
iDeveloper
la source
5
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
[cell setSelected:NO animated:NO];
[cell setHighlighted:NO animated:NO];

Bon codage !!!

Rinku Sadhwani
la source
5

Vous pouvez également le faire à partir du storyboard. Cliquez sur la cellule de vue tableau et dans l'inspecteur d'attributs sous Cellule vue tableau, modifiez la liste déroulante en regard de Sélection sur Aucun.

Cindy
la source