如何在表格视图单元格中的UILabel中添加UITapGestureRecognizer?

时间:2022-06-01 14:03:24

I am using a NIB file to layout a custom table view cell. This cell has a label with outlet called lblName. Adding a UITapGestureRecognizer to this label never fires the associated event. I have userInteractionEnabled = YES.

我正在使用NIB文件来布局自定义表格视图单元格。这个单元格有一个带有出口的标签,名为lblName。将UITapGestureRecognizer添加到此标签永远不会触发关联的事件。我有userInteractionEnabled = YES。

I'm guessing that the problem is that the UILabel is in a TableView and that the table/cell view is intercepting the taps. Can I do something about this?

我猜测问题是UILabel在TableView中并且表/单元视图拦截了水龙头。我能为此做些什么吗?

All I want to do is perform some custom action when a UILabel is pressed! All of the solutions for doing this that I've seen are ridiculous. It should be easy using the standard tool set. But evidently not.

我想要做的就是在按下UILabel时执行一些自定义操作!我所见过的所有解决方案都是荒谬的。使用标准工具集应该很容易。但显然不是。

Here's the code I'm using:

这是我正在使用的代码:

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

9 个解决方案

#1


22  

EASY WAY:

简单的方法:

You may also use a invisible button on the top of that label. So it will reduce your work of adding tapGesture for that label.

您也可以使用该标签顶部的隐形按钮。因此,它将减少为该标签添加tapGesture的工作。

ALTERNATIVE WAY:

替代方式:

You should not create an IBOutlet for that UILabel. When you do that,you will add a outlet in custom class implementation file. You cannot access in other file. So set a tag for that label in custom class IB and write a code in cellForRowAtIndexPath: method.

您不应该为该UILabel创建IBOutlet。执行此操作时,您将在自定义类实现文件中添加插座。您无法访问其他文件。因此,在自定义类IB中为该标签设置标记,并在cellForRowAtIndexPath:方法中编写代码。

UPDATED:

更新:

In cellForRowAtIndexPath: method,

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

#2


13  

UITapGestureRecognizer *recognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapAction)]; 
[recognizer setNumberOfTapsRequired:1];
lblName.userInteractionEnabled = YES;  
[lblName addGestureRecognizer:recognizer];

#3


10  

Doing this works without problems:

这样做没有问题:

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

even in the case in which creates the UILabel with IB

即使在使用IB创建UILabel的情况下也是如此

#4


5  

You can use below code to add tap gesture on UILable in UITableView cell

您可以使用以下代码在UITableView单元格中的UILable上添加点按手势

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

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

and to access the selector method

并访问选择器方法

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

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

#5


1  

Once you assign the tap gesture to the UILabel and set the user interaction to enabled, in your callback function you can find the indexpath from the cell view but searching through the nest of superviews:

将点击手势分配给UILabel并将用户交互设置为启用后,在回调函数中,您可以从单元格视图中找到索引路径,但搜索超级视图嵌套:

- (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;
}

#6


1  

For Swift 3

对于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)

And then

接着

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

#7


0  

The way Dinesh suggested will work without the for loop using the property variable.

Dinesh建议的方式将在没有使用属性变量的for循环的情况下工作。

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

#8


0  

You can add next in your cell's -awakeFromNib method

您可以在单元格的-awakeFromNib方法中添加next

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

#9


0  

For Swift, you can add this inside your cellForRowAtIndexPath method.

对于Swift,您可以在cellForRowAtIndexPath方法中添加它。

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

Then for 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.
}

#1


22  

EASY WAY:

简单的方法:

You may also use a invisible button on the top of that label. So it will reduce your work of adding tapGesture for that label.

您也可以使用该标签顶部的隐形按钮。因此,它将减少为该标签添加tapGesture的工作。

ALTERNATIVE WAY:

替代方式:

You should not create an IBOutlet for that UILabel. When you do that,you will add a outlet in custom class implementation file. You cannot access in other file. So set a tag for that label in custom class IB and write a code in cellForRowAtIndexPath: method.

您不应该为该UILabel创建IBOutlet。执行此操作时,您将在自定义类实现文件中添加插座。您无法访问其他文件。因此,在自定义类IB中为该标签设置标记,并在cellForRowAtIndexPath:方法中编写代码。

UPDATED:

更新:

In cellForRowAtIndexPath: method,

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

#2


13  

UITapGestureRecognizer *recognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapAction)]; 
[recognizer setNumberOfTapsRequired:1];
lblName.userInteractionEnabled = YES;  
[lblName addGestureRecognizer:recognizer];

#3


10  

Doing this works without problems:

这样做没有问题:

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

even in the case in which creates the UILabel with IB

即使在使用IB创建UILabel的情况下也是如此

#4


5  

You can use below code to add tap gesture on UILable in UITableView cell

您可以使用以下代码在UITableView单元格中的UILable上添加点按手势

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

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

and to access the selector method

并访问选择器方法

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

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

#5


1  

Once you assign the tap gesture to the UILabel and set the user interaction to enabled, in your callback function you can find the indexpath from the cell view but searching through the nest of superviews:

将点击手势分配给UILabel并将用户交互设置为启用后,在回调函数中,您可以从单元格视图中找到索引路径,但搜索超级视图嵌套:

- (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;
}

#6


1  

For Swift 3

对于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)

And then

接着

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

#7


0  

The way Dinesh suggested will work without the for loop using the property variable.

Dinesh建议的方式将在没有使用属性变量的for循环的情况下工作。

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

#8


0  

You can add next in your cell's -awakeFromNib method

您可以在单元格的-awakeFromNib方法中添加next

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

#9


0  

For Swift, you can add this inside your cellForRowAtIndexPath method.

对于Swift,您可以在cellForRowAtIndexPath方法中添加它。

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

Then for 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.
}