web-dev-qa-db-fra.com

Comment puis-je ajouter un UITapGestureRecognizer à un UILabel dans une cellule de vue de tableau?

J'utilise un fichier NIB pour mettre en forme une cellule d'affichage de tableau personnalisé. Cette cellule a une étiquette avec sortie appelée lblName. L'ajout d'un UITapGestureRecognizer à cette étiquette ne déclenche jamais l'événement associé. J'ai userInteractionEnabled = YES.

J'imagine que le problème est que UILabel est dans une table et que la vue table/cellule intercepte les taps. Puis-je faire quelque chose à ce sujet?

Tout ce que je veux faire, c'est exécuter une action personnalisée quand un UILabel est pressé! Toutes les solutions pour ce faire que j'ai vu sont ridicules. Cela devrait être facile en utilisant le jeu d’outils standard. Mais évidemment pas.

Voici le code que j'utilise:

- (void)tapAction {
    NSLog(@"Tap action");
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view from its nib

    UITapGestureRecognizer *recognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapAction)]; 
    [recognizer setNumberOfTapsRequired:1];
    //lblName.userInteractionEnabled = true;  (setting this in Interface Builder)
    [lblName addGestureRecognizer:recognizer];
}
22
Bryan

MOYEN FACILE:

Vous pouvez également utiliser un bouton invisible en haut de cette étiquette. Cela réduira donc votre travail d’ajout de tapGesture à cette étiquette. 

VOIE ALTERNATIVE:

Vous ne devez pas créer un IBOutlet pour cette UILabel. Lorsque vous faites cela, vous allez ajouter un point de vente dans un fichier d'implémentation de classe personnalisé. Vous ne pouvez pas accéder à un autre fichier. Donc, définissez une étiquette pour cette étiquette dans la classe personnalisée IB et écrivez un code dans la méthode cellForRowAtIndexPath:.

MIS À JOUR:

Dans la méthode cellForRowAtIndexPath:,

for(UIView *view in cell.contentViews.subviews) {
    if(view.tag == 1) {
        UITapGestureRecognizer *tap=[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapAction)];
        [tap setNumberOfTapsRequired:1];
        [view addGestureRecognizer:tap];
    }
}
23
Dinesh Raja
UITapGestureRecognizer *recognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapAction)]; 
[recognizer setNumberOfTapsRequired:1];
lblName.userInteractionEnabled = YES;  
[lblName addGestureRecognizer:recognizer];
13
sarit bahuguna

Cela fonctionne sans problèmes:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{
   ...
   // create you cell
   UILabel *lbl = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 100, 50)];
   [lbl setText:@"example"];
   [lbl setUserInteractionEnabled:YES];
   [cell.contentView addSubview:lbl];
   UITapGestureRecognizer *tap=[[UITapGestureRecognizer alloc] initWithTarget:self    action:@selector(tapAction:)];
   tap.tag = [NSIndexPath row];
   [tap setNumberOfTapsRequired:1];
   [lbl addGestureRecognizer:tap];
   ... 
}

- (void)tapAction:(id)sender {
  switch(((UITapGestureRecognizer *)sender).view.tag) {
     case 0:
          // code
          break;
     case 1:
         // code
         break;
      ....
     }
}

même dans le cas où crée le UILabel avec IB

10
WhiteTiger

Vous pouvez utiliser le code ci-dessous pour ajouter un geste de tapement sur UILabel dans UITableViewcell

UITapGestureRecognizer *tapGeature = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(lblClick:)];
tapGeature.delegate =self;
tapGeature.numberOfTapsRequired = 1;

cell.lbl.userInteractionEnabled = YES;
[cell.lbl addGestureRecognizer:tapGeature];

et pour accéder à la méthode de sélection

- (void)lblClick:(UITapGestureRecognizer *)tapGesture {
    UILabel *label = (UILabel *)tapGesture.view;
    NSLog(@"Lable tag is ::%ld",(long)label.tag);
}

Pour Swift

let tapGesture : UITapGestureRecognizer = UITapGestureRecognizer.init(target: self, action: #selector(lblClick(tapGesture:)))
tapGesture.delegate = self
tapGesture.numberOfTapsRequired = 1
cell.lbl.userInteractionEnabled = true
cell.lbl.tag = indexPath.row
cell.lbl.addGestureRecognizer(tapGesture)

func lblClick(tapGesture:UITapGestureRecognizer){
   print("Lable tag is:\(tapGesture.view!.tag)")
}
7
Hardik Thakkar

Une fois que vous avez affecté le geste de tapement à UILabel et que l'interaction utilisateur a été activée, dans votre fonction de rappel, vous pouvez rechercher le chemin d'index à partir de la vue de la cellule, mais en effectuant une recherche dans le nid de superviews:

- (UITableViewCell *) findCellInSuperview:(UIView *)view
{
UITableViewCell *cell = nil;

    NSString *className = NSStringFromClass([[view superview] class]);
    if ([className isEqualToString:@"UITableViewCell"]) {
        cell = (UITableViewCell *)[view superview];
    } else {
        if ([view superview] != nil) {
            cell = [self findCellInSuperview:[view superview]];
        }
    }

return cell;
}
1
adjwilli

Pour Swift 3

let tapGesture : UITapGestureRecognizer = UITapGestureRecognizer.init(target: self, action: 
#selector(lblClick(tapGesture:)))
tapGesture.delegate = self
tapGesture.numberOfTapsRequired = 1
cell.lbl.isUserInteractionEnabled = true
cell.lbl.tag = indexPath.row
cell.lbl.addGestureRecognizer(tapGesture)

Et alors

func lblClick(tapGesture:UITapGestureRecognizer){
    print("Lable tag is:\(tapGesture.view!.tag)")
}
1
fegoulart

La méthode suggérée par Dinesh fonctionnera sans la boucle for en utilisant la variable de propriété. 

UITapGestureRecognizer *tap=[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapAction)];
[tap setNumberOfTapsRequired:1];
[self.myUILabel addGestureRecognizer:tap];
0
Andrespch

Vous pouvez ajouter ensuite à la méthode -awakeFromNib de votre cellulaire

UITapGestureRecognizer* gesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapGestureRecognizerAction:)];
[self.yourLabel setUserInteractionEnabled:YES];
[self.yourLabel addGestureRecognizer:gesture];
0
landonandrey

Pour Swift, vous pouvez ajouter ceci dans votre méthode cellForRowAtIndexPath.

var tap = UITapGestureRecognizer(target: self, action: "labelTapped")
tap.numberOfTapsRequired = 1
cell.label.addGestureRecognizer(tap)
cell.label.tag = indexPath.row

Puis pour l'action 

func labelTapped(gesture: UITapGestureRecognizer) {
    let indexPath = NSIndexPath(forRow: gesture.view!.tag, inSection: 0)
    let cell = tableView.cellForRowAtIndexPath(indexPath) as UITableViewCell

    // Do whatever you want.
}
0
Leo Chan