29

我在视图中有UIViewController一个UITableView孩子,我想要做的是当我触摸任何一行时,我在底部显示一个视图。如果用户触摸行或底部视图之外的任何其他位置,我想隐藏该视图。

问题是当我点击UITableView它时不会触发touchesEnded事件。

现在我如何检测触摸UITableView并将其与行选择事件区分开来。

谢谢。

4

7 回答 7

54

无需子类化任何东西,您可以根据您的标准添加UITapGestureRecognizerUITableView吸收手势或不吸收手势。

在您看来DidLoad:

UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(didTapOnTableView:)];
[self.myTableView addGestureRecognizer:tap];

然后,针对标准执行您的操作:

-(void) didTapOnTableView:(UIGestureRecognizer*) recognizer {
    CGPoint tapLocation = [recognizer locationInView:self.myTableView];
    NSIndexPath *indexPath = [self.myTableView indexPathForRowAtPoint:tapLocation];

    if (indexPath) { //we are in a tableview cell, let the gesture be handled by the view
        recognizer.cancelsTouchesInView = NO;
    } else { // anywhere else, do what is needed for your case
        [self.navigationController popViewControllerAnimated:YES];
    }
}

请注意,如果您只想简单地在表格的任何位置点击点击,而不是在单元格行中的任何按钮上,您只需要使用上面的第一个代码片段。一个典型的例子是当你有一个 UITableView 并且还有一个 UISearchBar。当用户单击、滚动等表格视图时,您希望消除搜索栏。代码示例...

-(void)viewDidLoad {
    [super viewDidLoad];
    etc ...

    [self _prepareTable];
}
-(void)_prepareTable {
    self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
    self.tableView.allowsSelection = NO;
    etc...

    UITapGestureRecognizer *anyTouch =
        [[UITapGestureRecognizer alloc]
         initWithTarget:self action:@selector(tableTap)];
    [self.tableView addGestureRecognizer:anyTouch];
}
// Always drop the keyboard when the user taps on the table:
// This will correctly NOT affect any buttons in cell rows:
-(void)tableTap {
    [self.searchBar resignFirstResponder];
}
// You probably also want to drop the keyboard when the user is
// scrolling around looking at the table. If so:
-(void)scrollViewDidScroll:(UIScrollView *)scrollView {
    [self.searchBar resignFirstResponder];
}
// Finally you may or may not want to drop the keyboard when
// a button in one cell row is clicked. If so:
-(void)clickedSomeCellButton... {
    [self.searchBar resignFirstResponder];
    ...
}

希望它可以帮助某人。

于 2013-02-21T21:32:57.093 回答
14

You should forward the touch event to the view's controller. Subclass your tableview control and then override the method:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    [super touchesBegan:touches withEvent:event];  //let the tableview handle cell selection 
    [self.nextResponder touchesBegan:touches withEvent:event]; // give the controller a chance for handling touch events 
}

then , you can do what you want in the controller's touch methods.

于 2012-07-21T07:28:29.937 回答
8

我只是偶然发现了可能解决您问题的方法。创建表格视图时使用此代码:

tableView.canCancelContentTouches = NO;

如果不将此设置为NO,则只要表格视图中有一点垂直移动,触摸事件就会被取消(如果您将 NSLog 语句放入代码中,您会看到touchesCancelled表格开始滚动时立即调用它垂直)。

于 2011-10-21T20:13:56.437 回答
6

很长一段时间以来我一直面临这个问题并且没有任何有效的解决方案。最后我选择了另一种选择。我知道从技术上讲这不是解决方案,但这可能有助于肯定寻找相同解决方案的人。

在我的情况下,我想选择一行将显示一些选项,然后我触摸表格或视图上的任何位置我想隐藏这些选项或执行除之前选择的行之外的任何任务,我做了以下操作:

  1. 为视图设置触摸事件。当您触摸视图上除表格视图之外的任何位置时,这将完成任务。

  2. TableView 的 didSelectRowAtIndexPath 做以下

     - (void)tableView:(UITableView*)tableView didSelectRowAtIndexPath:(NSIndexPath*)indexPath {
        if(indexPath.row != previousSelectedRow && previousSelectedRow != -1) {
            // hide options or whatever you want to do
            previousSelectedRow = -1;
        }
        else {
            // show your options or other things
            previousSelectedRow = indexPath.row;
        }
     }
    

我知道这是较旧的帖子,不是一个好的技术解决方案,但这对我有用。我发布此答案是因为这肯定会对某人有所帮助。

注意:这里写的代码可能有拼写错误,因为这里是直接输入的。:)

于 2012-08-03T05:22:05.630 回答
3

试试这个方法:

- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{

}

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{

}

使用 scrollViewDidEndDragging 替代 touchesEnded。希望能帮助到你。

于 2015-04-27T11:43:39.530 回答
2

要接收有关使用的触摸事件UITableView

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
  //<my stuff>

  [super touchesBegan:touches withEvent:event];
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
   //<my stuff>

   [super touchesMoved:touches withEvent:event];
}

- (void)touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event
{
  //<my stuff>

  [super touchesEnded:touches withEvent:event];
}

- (void)touchesCancelled:(NSSet*)touches withEvent:(UIEvent*)event
{
   //<my stuff>
   [super touchesCancelled:touches withEvent:event];
}
于 2011-05-01T12:18:22.973 回答
-3

在您的控制器类中声明一个删除底部视图的方法。像这样的东西:

-(IBAction)bottomViewRemove:(id)sender {

[bottomView removeFromSuperview];

}

在 Interface Builder 中,选择您的视图,然后在自定义类部分的身份检查器中,将类从 更改UIViewUIControl。之后转到连接检查器并将 TouchUpInside 事件连接到上面声明的方法。希望这可以帮助。

于 2011-05-01T12:24:47.870 回答