在UITableView上触摸事件?

问题描述:

我有UIViewControllerUITableView作为孩子在视图中, 我想要做的是当我触摸任何行我显示底部的视图。如果用户触摸其他位置的行或bottomView,我想隐藏该视图。在UITableView上触摸事件?

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

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

谢谢。

+0

林不知道我明白。你是说你有一个拥有UITableView的UIView(viewA),和另一个UIView(viewB)(在底部)。如果用户触摸UiTableViewCell或viewB以外的任何地方,则希望隐藏viewB。否则,显示viewB。那是对的吗? – 2011-05-01 14:19:38

+0

是的正是我想要做的。如果用户触摸UITableViewCell我想显示viewB。我可以通过didRowSelectedAtIndexPath进行存档: – 2011-05-05 09:55:06

+0

那么你在问什么?“你如何捕获在UITableView上发生的触摸事件,而不是在单元格中? – 2011-05-05 15:34:31

我很长时间以来一直面临这个问题,并没有得到任何工作解决方案。最后,我选择了一个替代方案。我知道技术上这不是解决方案,但这可能有助于某人寻找相同的肯定。

在我来说,我要选择的行会显示一些选项后,我在任何地方触及表或视图我想隐藏这些选项或做任何任务,除了先前选择的行我也以下:

  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; 
        } 
    } 
    

我知道这是旧的文章,而不是一个良好的技术解决方案,但这个工作对我来说。我张贴这个答案,因为这可以帮助确定的人。

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

收到关于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]; 
} 

receive touch events in UITableView

在您的控制器类声明其去除底视图的方法。事情是这样的:

-(IBAction)bottomViewRemove:(id)sender { 

[bottomView removeFromSuperview]; 

} 

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

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

tableView.canCancelContentTouches = NO; 

没有这个设置为NO,因为甚至有垂直运动的在你的表视图(微微有点触摸事件,一旦取消,如果你把的NSLog声明在您的代码中,只要表开始垂直滚动,就会调用touchesCancelled)。

+1

您的解决方案不起作用。我试过你的解决方案,并用包括'touchesCledlled'在内的所有触摸事件。在'viewDidLoad'中,我设置了[[tblTemp setCanCancelContentTouches:NO];'。我的触摸方法没有被调用。 – 2012-07-23 04:30:25

您应该将触摸事件转发给视图的控制器。 子类的实现代码如下控件,然后重写方法:

- (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 
} 

然后,你可以做你在控制器的触摸方法想要什么。

+0

谢谢@longway,但我没有得到touchsBegan叫我比我怎么可以forwar它查看的控制器? 这个问题是关于如何调用touchesBegan事件,当我触摸tableView :) – 2012-07-21 11:26:07

+0

你子类UItableView,重写触摸手柄的方法。然后你创建你的表使用你自定义tableview类 – longway 2012-07-21 12:18:11

+0

嗨,我已经尝试过你的解决方案,当然可以检测tableview的topuch并传递给它相应的superview。坚果现在我有问题,即UITableview委托方法,即didSelectRowAtIndexPath没有得到调用。最终,我想要的是,首先检测触摸tableview传递它superview做一些行动,然后执行didSelectRowAtIndexPath。你能帮我吗? – 2013-08-02 10:54:51

不需要子类化任何东西,您可以将UITapGestureRecognizer添加到UITableView,并根据您的标准吸收手势。

在您的viewDidLoad:

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]; 
    ... 
} 

希望它可以帮助别人。

+1

我更喜欢在scrollViewWillBeginDragging中调用resignFirstResponder:(UIScrollView *)scrollView方法而不是scrollViewDidScroll。因为如果用户在滚动减速过程中将滚动然后单击searchBar - 键盘会在屏幕上出现一秒钟,然后它会隐藏,这不是一个合适的行为。使用scrollViewWillBeginDragging方法解决此问题。 – Werewolf 2016-10-20 09:04:44

试试这个方法:

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

} 

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

} 

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