16

我创建了一个UITableView带有自定义的UITableViewCell. 我的单元格包括UIImageView左侧和UITextView右侧的一个。

在里面UITableViewController,我在 tableview 中设置了图像和文本cellForRowAtIndexPath

一切都很好,但现在我需要实现didSelectRowAtIndex,我需要区分是否UIImageView单击UITextView了单元格。

比方说,图像点击代表删除操作和单元格编辑操作的其余部分。

4

5 回答 5

50

无需将手势识别器添加到每个单独的单元格,您可以将手势识别器添加到表格视图并确定从用户触摸点选择了哪个单元格,然后确定用户是否触摸了图像或单元格。

首先确保您的控制器采用 UIGestureRecognizerDelegate 协议。

@interface MyTableViewController() <UIGestureRecognizerDelegate>
@end

然后UIGestureRecognizerUITableView视图加载时添加 。

    - (void)viewDidLoad
{
    [super viewDidLoad];
    UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTap:)];
    singleTap.delegate = self;
    singleTap.numberOfTapsRequired = 1;
    singleTap.numberOfTouchesRequired = 1;
    [self.tableView addGestureRecognizer:singleTap];
}

此委托方法确定是否handleTap:应执行该方法。如果它可以indexPath从用户触摸中找到一个,则返回,YES否则返回NO

- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
{
    UITableView *tableView = (UITableView *)gestureRecognizer.view;
    CGPoint p = [gestureRecognizer locationInView:gestureRecognizer.view];
    if ([tableView indexPathForRowAtPoint:p]) {
        return YES;
    }
    return NO;
}

一旦我们确定用户是否点击了单元格,就会调用 handleTap: 方法,然后确定用户是否触摸了图像或单元格的任何其他部分。

- (void)handleTap:(UITapGestureRecognizer *)tap
{
    if (UIGestureRecognizerStateEnded == tap.state) {
        UITableView *tableView = (UITableView *)tap.view;
        CGPoint p = [tap locationInView:tap.view];
        NSIndexPath* indexPath = [tableView indexPathForRowAtPoint:p];
        [tableView deselectRowAtIndexPath:indexPath animated:NO];
        UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
        CGPoint pointInCell = [tap locationInView:cell];
        if (CGRectContainsPoint(cell.imageView.frame, pointInCell)) {
            // user tapped image
        } else {
            // user tapped cell
        }
    }
}
于 2012-06-17T12:16:07.737 回答
5

您可以继承UITableViewCell和覆盖touchesEnded.

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {

    [super touchesEnded:touches withEvent:event];

    UITouch *touch = [touches  anyObject];
    CGPoint location = [touch locationInView:self];

    UIView *hitView = [self hitTest:location withEvent:event];

    if (hitView == myImageView) ...;
    if (hitView == myTextView) ...;
}

您需要保留对您的UIImageView和的一些参考UITextView(它们可能应该是您的单元格的属性)。

您当然可以覆盖touchesBegan而不是touchesEnded,这取决于您要实现的功能。

于 2012-06-17T11:31:10.920 回答
1

使图像成为 UIButton。当按钮的动作被触发时,您知道用户点击了图像(不会选择单元格)。如果选择了单元格,则您知道用户点击了行上的其他位置(包括文本视图或标签)。

此外,将按钮的标签属性设置为,例如单元格的行索引,这样您就可以知道点击了哪一行的图像。

于 2012-06-17T12:09:49.767 回答
1

一个非常抽象和一般的答案是执行以下操作对于您添加的每个 UIImage 和 UILabel 将它们的标签设置为indexPath.row

//When creating the label and image add a recognizer to them
label.tag = indexPath.row;
imageView.tag = indexPath.row;

然后在每个图像和标签上添加一个 UITapGestureRecognizer ,就像这样

    UITapGestureRecognizer *recognizer = [[UITapGestureRecognizer alloc] initWithTarget:self 
                                                                                 action:@selector(handleTap:)];
    [label addGestureRecognizer:recognizer];
    [imageView addGestureRecognizer:recognizer];
}

- (void) handleTap:(UITapGestureRecognizer*)recognizer
{
    UIView *view = recognizer.view;
    int row = view.tag;
    if ([view isKindOfClass:[UILabel class]]) {
        //Row is row
        //and the label is pressed
    }

    if ([view isKindOfClass:[UIImageView class]]) {
        //Row is row
        //and the imageview is pressed
    }
}
于 2012-06-17T11:29:42.257 回答
0

您有两个选择是实现:- 1-在“uitableviewcell”中添加 UITapGestureRecognizer 并使其指向图像视图并将“indexpath”作为参数传递给选择器并使委托将其传递给 tableviewcell

UILabel *label = =[UILabel alloc]init];
label.userInteractionEnabled = YES;
UITapGestureRecognizer *tapGesture =
[[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(labelTap)]     autorelease];
[label addGestureRecognizer:tapGesture];


-(void)labelTap{
[delegate performselector@selector(labeltapped:)withobject:indexpath];
}

2- 第二种方法是检查类型 [imageview 或 label] 的 DidSelectRowAtIndexPath 的发件人;但我更喜欢第一种方式

于 2012-06-17T11:32:10.087 回答