在我的 iPhone 应用程序中,我有一个消息屏幕。我已经添加UITapGestureRecognizer
了,UIViewController
并且我UITableview
在屏幕上也有一个。我想选择,UITableViewCell
但我不能选择,UITableView
因为UITapGestureRecognizer
。当我触摸屏幕时,只调用点击手势动作但不调用UITableView
委托。didSelectRowAtIndexPath:
谁能帮我处理轻击手势和UITableView:didSelectRowAtIndexPath:
. 提前致谢。
4 回答
虽然我更喜欢 Matt Meyer 的建议或我使用自定义手势识别器的其他建议,但不涉及自定义手势识别器的另一种解决方案是让您的点击手势识别器识别您是否点击了表格视图中的单元格,如果是,则手动调用didSelectRowAtIndexPath
,例如:
- (void)handleTap:(UITapGestureRecognizer *)sender
{
CGPoint location = [sender locationInView:self.view];
if (CGRectContainsPoint([self.view convertRect:self.tableView.frame fromView:self.tableView.superview], location))
{
CGPoint locationInTableview = [self.tableView convertPoint:location fromView:self.view];
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:locationInTableview];
if (indexPath)
[self tableView:self.tableView didSelectRowAtIndexPath:indexPath];
return;
}
// otherwise proceed with the rest of your tap handling logic
}
这是次优的,因为如果您使用 tableview 做任何复杂的事情(例如,在单元格编辑、自定义控件等中),您会失去这种行为,但如果您只是想接收didSelectRowAtIndexPath
,那么这可能会完成这项工作。其他两种方法(单独的视图或自定义手势识别器)让您保留完整的 tableview 功能,但如果您只需要简单的东西并且不需要 tableview 的其余内置功能,这可能会起作用。
您可以使用 TagGesture 委托:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
if ([touch.view isDescendantOfView:yourTableView]) {
return NO;
}
return YES;
}
希望这可以帮助。
一种更简单的方法是拥有两个视图:一个包含您希望点击手势打开的视图,另一个包含表格视图。您可以将 UITapGestureRecognizer 附加到您希望它处理的视图上,然后它就不会阻塞您的 UITableView。
假设您希望点击手势在除了 tableview 之外的任何地方都可以工作,您可以对点击手势识别器进行子类化,创建一个识别器,该识别器将忽略数组中包含的任何子视图excludedViews
,从而阻止它们生成成功的手势(从而将其传递给didSelectRowAtIndexPath
或任何):
#import <UIKit/UIGestureRecognizerSubclass.h>
@interface MyTapGestureRecognizer : UITapGestureRecognizer
@property (nonatomic, strong) NSMutableArray *excludedViews;
@end
@implementation MyTapGestureRecognizer
@synthesize excludedViews = _excludedViews;
- (id)initWithTarget:(id)target action:(SEL)action
{
self = [super initWithTarget:target action:action];
if (self)
{
_excludedViews = [[NSMutableArray alloc] init];
}
return self;
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[super touchesBegan:touches withEvent:event];
CGPoint location = [[touches anyObject] locationInView:self.view];
for (UIView *excludedView in self.excludedViews)
{
CGRect frame = [self.view convertRect:excludedView.frame fromView:excludedView.superview];
if (CGRectContainsPoint(frame, location))
self.state = UIGestureRecognizerStateFailed;
}
}
@end
然后,当您想使用它时,只需指定要排除的控件:
MyTapGestureRecognizer *tap = [[MyTapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTap:)];
[tap.excludedViews addObject:self.tableView];
[self.view addGestureRecognizer:tap];