我在视图中添加了UIViewController
和UITableView
,现在我想要实现的是当我点击任意一行时,在底部显示一个视图。如果用户点击除行或底部视图以外的其他地方,我想要隐藏该视图。
问题是当我在UITableView
上点击时,它不会触发touchesEnded
事件。
那么如何检测UITableView
上的触摸事件并将其与选定行事件区分开呢?
谢谢。
我在视图中添加了UIViewController
和UITableView
,现在我想要实现的是当我点击任意一行时,在底部显示一个视图。如果用户点击除行或底部视图以外的其他地方,我想要隐藏该视图。
问题是当我在UITableView
上点击时,它不会触发touchesEnded
事件。
那么如何检测UITableView
上的触摸事件并将其与选定行事件区分开呢?
谢谢。
无需子类化任何内容,您可以向 UITableView
添加 UITapGestureRecognizer
,并根据您的标准吸收手势或不吸收手势。
在您的 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];
}
}
-(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];
...
}
- (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
}
那么,您可以在控制器的touch方法中实现想要的操作。
我刚刚偶然发现了可能解决你问题的方法。在创建表格视图时,请使用以下代码:
tableView.canCancelContentTouches = NO;
如果不将其设置为NO
,则只要表格视图出现轻微的垂直移动(如果在代码中使用NSLog语句,则会发现一旦表格开始垂直滚动,touchesCancelled
就会被调用),触摸事件就会被取消。
touchesCancelled
。在 viewDidLoad
中,我设置了 [tblTemp setCanCancelContentTouches:NO];
。但是我的任何触摸方法都没有被调用。 - Kapil Choubisa我长时间以来一直面临这个问题,没有找到任何可行的解决方案。最终我选择了另一种方法。我知道从技术上讲,这不是解决方案,但这肯定可以帮助寻找同样问题答案的人。
在我的情况下,我想选择一行,然后在点击表格或视图的任何位置后显示一些选项,我想隐藏那些选项或执行除之前选择的行之外的任何任务。为此,我进行了以下操作:
Set touch events for the view. This will do the task when you touch anywhere on the view except the table view.
TableView's didSelectRowAtIndexPath do following
- (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;
}
}
我知道这是旧帖子,不是一个好的技术解决方案,但是这对我起作用。我发布这个答案是因为这肯定会帮助到某些人。
注意:此处编写的代码可能有拼写错误,因为是直接输入的。 :)
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
}
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
}
要在 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];
}
-(IBAction)bottomViewRemove:(id)sender {
[bottomView removeFromSuperview];
}
UIView
更改为UIControl
。之后进入连接检查器,并将TouchUpInside事件连接到上面声明的方法。希望这可以帮助您。