Reputation: 3629
I'm got a tableview that displays custom view cells. In viewWillAppear i've setup a long press gesture recognizer that is on the UITableView. My long press is firing and displaying the info about the cell that has been long pressed upon. However when I let go of the press the didSelectRowAtIndexPath method is firing. Is there a way to cancel the touch after the long press fires, so that the select row doesn't get triggered?
I've seen didSelectRowAtIndexPath called after long press and that question does not seem to have an adequate answer as to how to fix the problem.
@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;
}
Upvotes: 1
Views: 1405
Reputation: 62676
While the gesture is active (begun but not ended) disable selection on the table view...
- (void)handleLongPress:(UILongPressGestureRecognizer *)gr {
if (gr.state == UIGestureRecognizerStateBegan) {
self.myTableview.allowsSelection = NO;
} else if (gr.state == UIGestureRecognizerStateEnded) {
self.myTableview.allowsSelection = YES;
}
}
No need to set the delegate, set cancelsTouches, or implement shouldRecognize... (unless you need these for something else).
EDIT This vc is a minimally complete test. It requires a storyboard with a table view wired to the outlet and the vc as the datasource and delegate...
#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
Upvotes: 3
Reputation: 285
You can disable tableview then only longGesture is working properly
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;
}
Upvotes: 0