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?


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 

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


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

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!)


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.


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


2
Meilleure solution à mon humble avis
Itai Spector

J'utilise souvent cette solution
Evsenev


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


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.


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

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;

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.


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


}

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

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)
}

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


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


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

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.


10

J'utilise ceci, qui fonctionne pour moi.

cell?.selectionStyle = UITableViewCellSelectionStyle.None

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];
...
}

7

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

entrez la description de l'image ici


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;

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.


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.


C'est maintenant cell.selectionStyle = UITableViewCellSelectionStyle.nonedans Swift 3.
Dan

5

Vous pouvez utiliser ceci

cell.selectionStyle = UITableViewCellSelectionStyleNone;

5

Vous pouvez utiliser ....

[cell setSelectionStyle:UITableViewCellSelectionStyleNone];


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

Bon codage !!!


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.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.