如何将UITapGestureRecognizer添加到表格视图单元格内的UILabel中?

问题描述:

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

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

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

下面是我使用的代码:

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

EASY WAY创建的UILabel :

您也可以使用隐形b utton在该标签的顶部。所以它会减少您为该标签添加tapGesture的工作。

另一种方式:

你不应该为UILabel创建一个IBOutlet。当你这样做时,你会在自定义类实现文件中添加一个插座。您无法在其他文件中访问。因此,在自定义类IB中为该标签设置标签,并在cellForRowAtIndexPath:方法中编写代码。

更新:

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]; 
    } 
} 
+0

谢谢,这个伎俩!在你的代码中修正一些错别字:首先“if”应当是“for”,然后你想枚举cell.contentViews.subviews。感谢你的回答! – Bryan 2012-04-10 19:11:34

+0

哦,我在这里输入了自己的名字。所以有一点小错误,我会更新它。 – 2012-04-11 04:41:53

+3

直到我在单元本身设置了“用户交互启用”后,这才起作用 – 2014-08-05 15:16:25

这样做的工作没有问题:

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

即使在情况下,与IB

+0

这将帮助他。但是他需要用Tap手势在UITableViewCell内创建一个标签。 – 2012-04-10 10:34:03

+0

然后在创建单元格的方法中,当您创建UITapGestureRecognizer时,为其添加标签并管理处理程序中用于区分标签的事件。 – WhiteTiger 2012-04-10 12:18:21

+0

你能解释一下代码吗? – 2012-04-10 12:46:21

方式的Dinesh建议的for循环使用属性变量而不将工作。

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

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

需要将userInteractionEnabledProperty设置为YES。在我的情况下,标签是在另一个视图内,没有这个,手势不起作用。 – alcamla 2015-12-17 23:14:09

一旦指定点击手势到的UILabel和用户交互设置为启用,在你的回调函数,你可以你可以添加在你的细胞的-awakeFromNib方法

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

下一个从单元格视图中查找索引路径,但在超级视图中搜索:

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

对于Swift , 你可以在你的cellForRowAtIndexPath方法中添加这个。

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

然后,对于动作

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

OP询问Objective-C问题,而不是Swift。 – 2015-05-09 14:04:42

+1

你有什么会导致运行时错误。 'action:“labelTapped”'说这个方法期望在没有任何参数的情况下被调用,但是这个方法的签名表明否则。 – maml 2015-06-24 00:42:43

+0

表格视图单元格是**重用**;是否存在将手势识别器多次添加到相同单元的风险? (同样的问题也适用于包含在单元格内的按钮中的“addTarget:action:forControlEvents:')。 – 2016-11-25 05:13:23

可以使用以下代码来对UILable添加敲击手势中的UITableView细胞

UITapGestureRecognizer *lblAction = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(lblClick:)]; 
lblAction.delegate =self; 
lblAction.numberOfTapsRequired = 1; 
cell.lbl.userInteractionEnabled = YES; 
[cell.lbl addGestureRecognizer:lblAction]; 

和访问选择方法

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

对于斯威夫特

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

对于斯威夫特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) 

然后

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