如何从UITableView iphone获取UITableView IndexPath?

问题描述:

在我的iPhone应用程序中,我有一个消息屏幕。我在UIViewController上添加了UITapGestureRecognizer,并且屏幕上还有UITableview。我想选择UITableViewCell,但由于UITapGestureRecognizer,我无法选择UITableView。当我触摸屏幕时,只调用点击手势动作,但不调用UITableView代表didSelectRowAtIndexPath:。任何人都可以请帮我做点击手势和UITableView:didSelectRowAtIndexPath:。提前致谢。如何从UITableView iphone获取UITableView IndexPath?

+0

您的tableview是屏幕上唯一的视图,还是它是层次结构的一部分? – 2012-08-13 13:41:46

+0

感谢您的回复。不,tableview和UIToolbar作为子视图在屏幕上。 – Gopinath 2012-08-13 13:43:34

+3

行为应该如何工作? tapgesturerecognizer应该做什么以及什么时候做? – 2012-08-13 13:45:19

虽然我更喜欢马特迈尔的建议或我使用自定义手势识别器的另一个解决方案,不涉及自定义手势识别器的其他解决方案的建议是让您的手势识别器识别您是否在桌面视图中单击某个单元格,如果是,则手动调用例如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; 
} 

希望这有助于。

+1

我不确定如果'touch.view'在'UIViewController'上,它就可以工作。但我认为这个想法是正确的:你可以肯定地看看tap的位置,并将它与tableview的框架进行比较,以获得CGPoint位置= [gestureRecognizer locationInView:self.view];'然后比较if( CGRectContainsPoint(self.tableView.frame,location))...' – Rob 2012-08-13 13:52:16

+0

@Rob我会再检查一下。感谢您的信息。 – NSPunk 2012-08-13 13:54:17

一个更简单的方法是拥有两个视图:一个视图包含您想要点按手势的视图,另一个视图包含桌面视图。您可以将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];