web-dev-qa-db-fra.com

UITableview: Comment désactiver la sélection de certaines lignes mais pas d'autres

J'affiche dans un groupe tableview un contenu analysé à partir de XML. Je veux désactiver l'événement click sur celui-ci (je ne devrais pas être capable de cliquer dessus du tout) La table contient deux groupes. Je souhaite désactiver la sélection du premier groupe uniquement, mais pas du deuxième groupe. En cliquant sur la première rangée du deuxième groupe navigates dans mon tube player view.

Comment puis-je sélectionner uniquement des groupes ou des lignes spécifiques?

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
{
    if(indexPath.section!=0)
    if(indexPath.row==0)    

    [[UIApplication sharedApplication] openURL:[NSURL URLWithString:tubeUrl]];   
}

Merci.

279
Warrior

Vous devez juste 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 = UITableViewCellSelectionStyleNone;

Pour permettre de sélectionner (toucher) la cellule: (appuyer sur la cellule)

// Default style
cell.selectionStyle = UITableViewCellSelectionStyleBlue;

// Gray style
cell.selectionStyle = UITableViewCellSelectionStyleGray;

Notez qu'une cellule avec selectionStyle = UITableViewCellSelectionStyleNone; fera toujours en sorte que l'interface utilisateur appelle didSelectRowAtIndexPath lorsqu'elle est touchée par l'utilisateur. Pour éviter cela, procédez comme indiqué ci-dessous et réglez.

cell.userInteractionEnabled = NO;

au lieu. Notez également que vous pouvez définir cell.textLabel.enabled = NO; pour griser l’élément.

476
Pugal

Si vous souhaitez créer une ligne (ou un sous-ensemble de lignes) non-sélectionnable, implémentez la méthode UITableViewDelegate-tableView:willSelectRowAtIndexPath: (également mentionnée par TechZen). Si indexPath ne doit pas être à sélectionner, retournez nil, sinon, retournez indexPath. Pour obtenir le comportement de sélection par défaut, vous renvoyez simplement le indexPath transmis à votre méthode delegate, mais vous pouvez également modifier la sélection de ligne en renvoyant un indexPath différent.

exemple:

- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    // rows in section 0 should not be selectable
    if ( indexPath.section == 0 ) return nil;

    // first 3 rows in any section should not be selectable
    if ( indexPath.row <= 2 ) return nil;

    // By default, allow row to be selected
    return indexPath;
}
348
Brian Chapados

À partir de iOS 6, vous pouvez utiliser

-tableView:shouldHighLightRowAtIndexPath:

Si vous renvoyez NO, il désactive à la fois la mise en surbrillance de la sélection et les séquences déclenchées par le storyboard connectées à cette cellule.

La méthode est appelée quand une touche tombe sur une ligne. Le fait de retourner NO à ce message interrompt le processus de sélection et ne provoque pas la perte de l'apparence sélectionnée de la ligne actuellement sélectionnée tant que le toucher est enfoncé.

Référence du protocole UITableViewDelegate

55
Keller

Aucune des réponses ci-dessus ne résout réellement le problème. La raison en est que nous voulons désactiver la sélection de la cellule mais pas nécessairement des sous-vues à l'intérieur de la cellule.

Dans mon cas, je présentais un UISwitch au milieu de la ligne et je voulais désactiver la sélection pour le reste de la ligne (qui est vide), mais pas pour le commutateur! La bonne façon de le faire est donc dans la méthode

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath

où une déclaration de la forme

[cell setSelectionStyle:UITableViewCellSelectionStyleNone];

désactive la sélection de la cellule spécifique tout en permettant à l'utilisateur de manipuler le commutateur et d'utiliser le sélecteur approprié. Ce n'est pas vrai si quelqu'un désactive l'interaction de l'utilisateur via le

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

méthode qui se contente de préparer la cellule et ne permet pas l’interaction avec le commutateur UISwitch.

De plus, en utilisant la méthode

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath

afin de désélectionner la cellule avec une déclaration de la forme

[tableView deselectRowAtIndexPath:indexPath animated:NO];

affiche toujours la ligne en cours de sélection pendant que l'utilisateur appuie sur le contentView d'origine de la cellule.

Juste mes deux cents. Je suis sûr que beaucoup trouveront cela utile.

16
MightyMouse

Vous intercepter des sélections avec ces méthodes de source de données.

– tableView:willSelectRowAtIndexPath: 
– tableView:didSelectRowAtIndexPath: 
– tableView:willDeselectRowAtIndexPath: 
– tableView:didDeselectRowAtIndexPath:

Dans ces méthodes, vous vérifiez si la ligne sélectionnée est celle que vous souhaitez sélectionner. Si c'est le cas, agissez, sinon, ne faites rien.

Malheureusement, vous ne pouvez pas désactiver la sélection pour une seule section. C'est la table entière ou rien.

Vous pouvez toutefois définir la propriété de cellules de tableau selectionStyle sur UITableViewCellSelectionStyleNone. Je crois que cela rendra la sélection invisible. Combinées aux méthodes ci-dessus, les cellules doivent avoir l'air complètement inertes du point de vue de l'utilisateur.

Edit01:

Si vous avez une table dans laquelle seules certaines des lignes sont sélectionnables, il est important que les cellules des lignes sélectionnables soient visuellement distinctes des lignes non sélectionnables. Le bouton accessoire en chevron est le moyen par défaut de le faire.

Quoi que vous fassiez, vous ne voulez pas que vos utilisateurs essaient de sélectionner des lignes et pensent que l'application a mal fonctionné, car la ligne ne fait rien.

11
TechZen

Pour Swift 4. par exemple:

cell.isUserInteractionEnabled = false
cell.contentView.alpha = 0.5
9

Pour désactiver la sélection de cellules dans la méthode cellForRowAtIndexPath, vous devez procéder de la manière suivante:

[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
[cell setUserInteractionEnabled:NO];

Pour afficher la cellule grisée, insérez ce qui suit dans la méthode tableView:WillDisplayCell:forRowAtIndexPath:

[cell setAlpha:0.5];

Une méthode vous permet de contrôler l'interactivité, l'autre vous permet de contrôler l'apparence de l'interface utilisateur.

9
azfar

Ma solution basée sur le modèle de données:

func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? {
    let rowDetails = viewModel.rowDetails(forIndexPath: indexPath)
    return rowDetails.enabled ? indexPath : nil
}

func tableView(_ tableView: UITableView, shouldHighlightRowAt indexPath: IndexPath) -> Bool {
    let rowDetails = viewModel.rowDetails(forIndexPath: indexPath)
    return rowDetails.enabled
}
5
SoftDesigner

Pour arrêter uniquement la sélection de certaines cellules, utilisez:

cell.userInteractionEnabled = NO;

En plus d'empêcher la sélection, cela arrête également tableView: didSelectRowAtIndexPath: en cours d'appel pour les cellules qui l'ont défini.

5
JosephH

Vous pouvez utiliser la méthode tableView:willDisplayCell pour effectuer tous les types de personnalisation en tableViewCell.

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
     [cell setSelectionStyle:UITableViewCellSelectionStyleNone];
     [cell setUserInteractionEnabled:NO];

     if (indexPath.section == 1 && indexPath.row == 0)
     {
         [cell setSelectionStyle:UITableViewCellSelectionStyleGray];
         [cell setUserInteractionEnabled:YES];
     }
} 

Dans ce code ci-dessus, l'utilisateur ne peut sélectionner que la première ligne de la deuxième section de la tableView. Les autres lignes ne peuvent pas être sélectionnées. Merci! ~

4
Abdul Rahman

Pour Swift 4.0 Cela fera l'affaire. Il désactivera la cellule dans la méthode didSelectRowAtIndexPath mais maintiendra les sous-vues cliquables.

func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? {
         if (indexPath.row == clickableIndex ) { 
            return indexPath
         }else{
            return nil
        }
    }
4
Nilesh

Pour Swift:

cell.selectionStyle = .None
cell.userInteractionEnabled = false
3
Esqarrouth

SIMPLE

Utilisez simplement cell.userInteractionEnabled = YES; pour la cellule si elle peut naviguer et cell.userInteractionEnabled = NO; sinon

1
Rick Royd Aban

J'ai trouvé cela pratique car cela fonctionne avec les tables statiques et dynamiques. Je ne mets l'indicateur de divulgation que sur les cellules que je souhaite autoriser.

- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
    if (cell.accessoryType != UITableViewCellAccessoryDisclosureIndicator) {
        return nil;
    }
    return indexPath;
}
1
Jeffery Jones

Utilisez ceci pour rendre la cellule ressembler à elle est désactivée et non sélectionnable:

cell.selectionStyle = UITableViewCellSelectionStyleNone;

Important: notez qu'il s'agit uniquement d'une propriété de style et ne désactive pas réellement la cellule. Pour ce faire, vous devez vérifier selectionStyle dans votre implémentation de délégué didSelectRowAtIndexPath::

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
    if(cell.selectionStyle == UITableViewCellSelectionStyleNone) {
        return;
    }

    // do your cell selection handling here
}
1
pt2ph8

J'aime Brian Chapados répondre ci-dessus. Toutefois, cela signifie que la logique peut être dupliquée à la fois dans cellForRowAtIndexPath, puis dans willSelectRowAtIndexPath, ce qui peut facilement être désynchronisé. Au lieu de dupliquer la logique, vérifiez simplement le selectionStyle:

- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
    if (cell.selectionStyle == UITableViewCellSelectionStyleNone)
        return nil;

    else
        return indexPath;
}
1
Eric D'Souza

sur Xcode 7 sans coder, vous pouvez simplement procéder comme suit:

Dans la vue hiérarchique, sélectionnez Cellule d'affichage du tableau. (La cellule est imbriquée sous Scène de contrôleur de vue de tableau> Contrôleur de vue de tableau> Vue de tableau. Vous devrez peut-être divulguer ces objets pour voir la cellule de vue de tableau.)

Dans l'inspecteur Attributs, recherchez le champ intitulé Sélection et sélectionnez Aucun. inspecteur d’attributs Avec cette option, la cellule n’obtient pas de surbrillance visuelle lorsqu'un utilisateur la tape.

1
Tung Fam

Implémentez uniquement la méthode tableView:willSelectRowAtIndexPath: dans la source de données de votre table. Si vous souhaitez que la ligne du chemin soit mise en surbrillance, renvoyez le chemin indexPath donné. Si vous ne le faites pas, renvoyez nil.

Exemple de mon application:

- (NSIndexPath *)tableView:(UITableView *)tableView
    willSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    MySelectableObj* obj = [self objectAtPath:indexPath];
    if(obj==nil) return nil;
    return indexPath;
}

La bonne chose à propos de cela est que shouldPerformSegueWithIdentifier:sender: ne sera pas appelé si la méthode ci-dessus renvoie nil, bien que je répète le test ci-dessus juste pour compléter.

0
user3821934

Pour Xcode 6.3:

 cell.selectionStyle = UITableViewCellSelectionStyle.None;
0
uplearnedu.com

Je suis d'accord avec la réponse de Bryan

si je fais

cell.isUserInteractionEnabled = false 

alors les sous-vues de la cellule ne seront pas interagies par l'utilisateur.

Sur l'autre site, le réglage

cell.selectionStyle = .none

déclenchera la méthode didSelect sans mettre à jour la couleur de sélection.

Avec willSelectRowAt, j'ai résolu mon problème. Exemple:

func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? {

    if indexPath.section == 0{

        if indexPath.row == 0{
            return nil
        }

    }
    else if indexPath.section == 1{

        if indexPath.row == 0{
            return nil
        }

    }

    return indexPath

}
0
Reimond Hill