在UITableView上触摸事件?

Kap*_*isa 28 iphone uitableview uiviewcontroller touches

我有UIViewControllerUITableView作为孩子在视图中,我想要做的是当我触摸任何行时,我在底部显示视图.如果用户触摸除了行或bottomView之外的任何其他位置,我想要隐藏该视图.

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

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

谢谢.

Dav*_*vid 51

无需任何类继承,您可以添加UITapGestureRecognizerUITableView和吸收手势或不依赖于你的标准.

在你的viewDidLoad中:

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

然后,按照以下标准实施此操作:

-(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];
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意,如果您只想在桌面上的任何位置单击,而不是单元格行中的任何按钮,则只需使用上面的第一个代码片段.一个典型的例子是当你有一个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];
    ...
}
Run Code Online (Sandbox Code Playgroud)

希望它可以帮助某人.


小智 14

您应该将触摸事件转发到视图的控制器.对tableview控件进行子类化,然后覆盖该方法:

- (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 
}
Run Code Online (Sandbox Code Playgroud)

然后,您可以在控制器的触摸方法中执行您想要的操作.


Mus*_*sis 8

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

tableView.canCancelContentTouches = NO;
Run Code Online (Sandbox Code Playgroud)

如果不对此进行设置NO,只要表视图中有一点点垂直移动,就会取消触摸事件(如果在代码中放置了NSLog语句,则会touchesCancelled在表开始滚动时立即调用垂直).

  • 你的解决方案不起作用。我尝试了您的解决方案并使用了所有带有日志的触摸事件,包括“touchesCancelled”。在“viewDidLoad”中,我设置了“[tblTemp setCanCancelContentTouches:NO];”。我的触摸方法没有被调用。 (2认同)

Kap*_*isa 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;
        }
     }
    
    Run Code Online (Sandbox Code Playgroud)

我知道这是较老的帖子而不是一个好的技术解决方案,但这对我有用.我发布这个答案是因为这可能对某些人有所帮助.

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