长按后如何取消触摸?
How do I cancel touches after long press?
我有一个显示自定义视图单元格的表格视图。在 viewWillAppear 中,我在 UITableView 上设置了一个长按手势识别器。我的长按正在触发并显示有关长期按下的单元格的信息。但是,当我松开按键时,didSelectRowAtIndexPath 方法正在触发。有没有办法在长按触发后取消触摸,这样 select 行就不会被触发?
我已经看到 并且这个问题似乎没有关于如何解决问题的充分答案。
@implementation ViewController
UILongPressGestureRecognizer *lpgr;
.
.
.
- (void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
// setup long press
lpgr = [[UILongPressGestureRecognizer alloc]
initWithTarget:self action:@selector(handleLongPress:)];
lpgr.minimumPressDuration = 0.5; //seconds
lpgr.delegate = self;
lpgr.cancelsTouchesInView = true;
[self.myTableview addGestureRecognizer:lpgr];
[self.myTableview.panGestureRecognizer requireGestureRecognizerToFail:lpgr]; ...
.
.
.
-(void)handleLongPress:(UILongPressGestureRecognizer *)gestureRecognizer
{
if (gestureRecognizer.state == UIGestureRecognizerStateBegan) {
CGPoint p = [gestureRecognizer locationInView:self.myTableview];
NSIndexPath *indexPath = [self.myTableview indexPathForRowAtPoint:p];
if (indexPath == nil) {
NSLog(@"long press on table view but not on a row");
} else {
UITableViewCell *cell = [self.myTableview cellForRowAtIndexPath:indexPath];
CensusData *currentUser;
if(self.isFiltered){
currentUser = (CensusData*)[self.filteredTableData objectAtIndex:indexPath.row];
}else{
currentUser = (CensusData*)[self.dataArray objectAtIndex:indexPath.row];
}
NSLog(@"CURRENT ROW WITH LONG PRESS: %@", currentUser.friendlyName);
}
}
}
.
.
.
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer
shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer{
return YES;
}
当手势处于活动状态(开始但未结束)时,禁用 table 视图上的选择...
- (void)handleLongPress:(UILongPressGestureRecognizer *)gr {
if (gr.state == UIGestureRecognizerStateBegan) {
self.myTableview.allowsSelection = NO;
} else if (gr.state == UIGestureRecognizerStateEnded) {
self.myTableview.allowsSelection = YES;
}
}
无需设置委托、设置 cancelsTouches 或实施 shouldRecognize...(除非您需要这些用于其他目的)。
编辑 这个vc 是一个最低限度的完整测试。它需要一个带有连接到插座的 table 视图和 vc 作为数据源和委托的故事板...
#import "ViewController.h"
@interface ViewController () <UITableViewDataSource, UITableViewDelegate>
@property(weak,nonatomic) IBOutlet UITableView *tableView;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
UILongPressGestureRecognizer *gr = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleLongPress:)];
[self.tableView addGestureRecognizer:gr];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 50;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell" forIndexPath:indexPath];
cell.textLabel.text = [NSString stringWithFormat:@"Row %ld", indexPath.row];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(@"selected %@", indexPath);
}
- (void)handleLongPress:(UILongPressGestureRecognizer *)gr {
if (gr.state == UIGestureRecognizerStateBegan) {
NSLog(@"long press began");
self.tableView.allowsSelection = NO;
} else if (gr.state == UIGestureRecognizerStateEnded) {
NSLog(@"long press ended");
self.tableView.allowsSelection = YES;
}
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
您可以禁用 tableview,然后只有 longGesture 可以正常工作
UILongPressGestureRecognizer* longPressRecognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(onLongPress:)];
[self.myTableview addGestureRecognizer:longPressRecognizer];
-(void)onLongPress:(UILongPressGestureRecognizer*)pGesture
{
if (pGesture.state == UIGestureRecognizerStateRecognized)
{
//Do something to tell the user!
}
if (pGesture.state == UIGestureRecognizerStateEnded)
{
CGPoint p = [pGesture locationInView:self.myTableview];
NSIndexPath *indexPath = [self.myTableview indexPathForRowAtPoint:p];
}
}
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch{
if ([touch.view isDescendantOfView:self.myTableview]) {
// Don't let selections of auto-complete entries fire the
// gesture recognizer
return NO;
}
return YES;
}
我有一个显示自定义视图单元格的表格视图。在 viewWillAppear 中,我在 UITableView 上设置了一个长按手势识别器。我的长按正在触发并显示有关长期按下的单元格的信息。但是,当我松开按键时,didSelectRowAtIndexPath 方法正在触发。有没有办法在长按触发后取消触摸,这样 select 行就不会被触发?
我已经看到
@implementation ViewController
UILongPressGestureRecognizer *lpgr;
.
.
.
- (void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
// setup long press
lpgr = [[UILongPressGestureRecognizer alloc]
initWithTarget:self action:@selector(handleLongPress:)];
lpgr.minimumPressDuration = 0.5; //seconds
lpgr.delegate = self;
lpgr.cancelsTouchesInView = true;
[self.myTableview addGestureRecognizer:lpgr];
[self.myTableview.panGestureRecognizer requireGestureRecognizerToFail:lpgr]; ...
.
.
.
-(void)handleLongPress:(UILongPressGestureRecognizer *)gestureRecognizer
{
if (gestureRecognizer.state == UIGestureRecognizerStateBegan) {
CGPoint p = [gestureRecognizer locationInView:self.myTableview];
NSIndexPath *indexPath = [self.myTableview indexPathForRowAtPoint:p];
if (indexPath == nil) {
NSLog(@"long press on table view but not on a row");
} else {
UITableViewCell *cell = [self.myTableview cellForRowAtIndexPath:indexPath];
CensusData *currentUser;
if(self.isFiltered){
currentUser = (CensusData*)[self.filteredTableData objectAtIndex:indexPath.row];
}else{
currentUser = (CensusData*)[self.dataArray objectAtIndex:indexPath.row];
}
NSLog(@"CURRENT ROW WITH LONG PRESS: %@", currentUser.friendlyName);
}
}
}
.
.
.
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer
shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer{
return YES;
}
当手势处于活动状态(开始但未结束)时,禁用 table 视图上的选择...
- (void)handleLongPress:(UILongPressGestureRecognizer *)gr {
if (gr.state == UIGestureRecognizerStateBegan) {
self.myTableview.allowsSelection = NO;
} else if (gr.state == UIGestureRecognizerStateEnded) {
self.myTableview.allowsSelection = YES;
}
}
无需设置委托、设置 cancelsTouches 或实施 shouldRecognize...(除非您需要这些用于其他目的)。
编辑 这个vc 是一个最低限度的完整测试。它需要一个带有连接到插座的 table 视图和 vc 作为数据源和委托的故事板...
#import "ViewController.h"
@interface ViewController () <UITableViewDataSource, UITableViewDelegate>
@property(weak,nonatomic) IBOutlet UITableView *tableView;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
UILongPressGestureRecognizer *gr = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleLongPress:)];
[self.tableView addGestureRecognizer:gr];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 50;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell" forIndexPath:indexPath];
cell.textLabel.text = [NSString stringWithFormat:@"Row %ld", indexPath.row];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(@"selected %@", indexPath);
}
- (void)handleLongPress:(UILongPressGestureRecognizer *)gr {
if (gr.state == UIGestureRecognizerStateBegan) {
NSLog(@"long press began");
self.tableView.allowsSelection = NO;
} else if (gr.state == UIGestureRecognizerStateEnded) {
NSLog(@"long press ended");
self.tableView.allowsSelection = YES;
}
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
您可以禁用 tableview,然后只有 longGesture 可以正常工作
UILongPressGestureRecognizer* longPressRecognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(onLongPress:)];
[self.myTableview addGestureRecognizer:longPressRecognizer];
-(void)onLongPress:(UILongPressGestureRecognizer*)pGesture
{
if (pGesture.state == UIGestureRecognizerStateRecognized)
{
//Do something to tell the user!
}
if (pGesture.state == UIGestureRecognizerStateEnded)
{
CGPoint p = [pGesture locationInView:self.myTableview];
NSIndexPath *indexPath = [self.myTableview indexPathForRowAtPoint:p];
}
}
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch{
if ([touch.view isDescendantOfView:self.myTableview]) {
// Don't let selections of auto-complete entries fire the
// gesture recognizer
return NO;
}
return YES;
}