问题
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.
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?
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.
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];
}
回答1:
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.
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.
UPDATED:
In cellForRowAtIndexPath:
method,
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:
UITapGestureRecognizer *recognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapAction)];
[recognizer setNumberOfTapsRequired:1];
lblName.userInteractionEnabled = YES;
[lblName addGestureRecognizer:recognizer];
回答3:
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
回答4:
You can use below code to add tap gesture on UILable in UITableView cell
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:
You can add next in your cell's -awakeFromNib method
UITapGestureRecognizer* gesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapGestureRecognizerAction:)];
[self.yourLabel setUserInteractionEnabled:YES];
[self.yourLabel addGestureRecognizer:gesture];
回答6:
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:
- (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;
}
回答7:
For 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)")
}
回答8:
The way Dinesh suggested will work without the for loop using the property variable.
UITapGestureRecognizer *tap=[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapAction)];
[tap setNumberOfTapsRequired:1];
[self.myUILabel addGestureRecognizer:tap];
回答9:
For Swift, you can add this inside your cellForRowAtIndexPath method.
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.
}
来源:https://stackoverflow.com/questions/10079019/how-can-i-add-a-uitapgesturerecognizer-to-a-uilabel-inside-a-table-view-cell