Problems using UIPanGestureRecognizer in UITableViewCell
ios, objective-c, uigesturerecognizer, uitableview
Solution
If you don't want the cell's swipe gesture to happen simultaneously with the table view scroll gesture, then add a pan gesture to your cell and make it a delegate:
UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(doPan:)];
pan.delegate = self;
[self addGestureRecognizer:pan];
And implement the following delegate method to only start if the pan is horizontal:
#pragma mark - UIGestureRecognizerDelegate
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
{
// note: we might be called from an internal UITableViewCell long press gesture
if ([gestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]]) {
UIPanGestureRecognizer *panGestureRecognizer = (UIPanGestureRecognizer*)gestureRecognizer;
UIView *cell = [panGestureRecognizer view];
CGPoint translation = [panGestureRecognizer translationInView:[cell superview]];
// Check for horizontal gesture
if (fabs(translation.x) > fabs(translation.y))
{
return YES;
}
}
return NO;
}
Swift3 ..
override func awakeFromNib() {
super.awakeFromNib()
// do not use, say, layoutSubviews as layoutSubviews is called often
let p = UIPanGestureRecognizer(target: self, action: #selector(yourPan))
p.delegate = self
contentView.addGestureRecognizer(p)
}
}
override func gestureRecognizerShouldBegin(_ g: UIGestureRecognizer) -> Bool {
if (g.isKind(of: UIPanGestureRecognizer.self)) {
let t = (g as! UIPanGestureRecognizer).translation(in: contentView)
let verticalness = abs(t.y)
if (verticalness > 0) {
print("ignore vertical motion in the pan ...")
print("the event engine will >pass on the gesture< to the scroll view")
return false
}
}
return true
}
Problem
I'm trying to implement a UIPanGestureRecognizer in my UITableViewController to use for a swipe to delete animation. Similar to the swipe to delete used in the Clear app, where if you swipe a UITableViewCell in left or right the cell moves and gets deleted. I have tried implementing this in my UITableViewCell subclass but it never seems to receive the event. This is the code I put in my UITableViewCell subclass to try this functionality. In my init method ``` UIGestureRecognizer *recognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan:)]; recognizer.delegate = self; [self addGestureRecognizer:recognizer]; ``` and then the methods to handle it: ``` - (BOOL)gestureRecognizerShouldBegin:(UIPanGestureRecognizer *)gestureRecognizer { CGPoint translation = [gestureRecognizer translationInView:self.superview]; //might have to change view to tableView //check for the horizontal gesture if (fabsf(translation.x) > fabsf(translation.y)) { return YES; NSLog(@"Panning"); } return NO; } - (void)handlePan:(UIPanGestureRecognizer *)recognizer { if (recognizer.state == UIGestureRecognizerStateBegan) { //if the gesture has just started record the center location NSLog(@"handlePan"); _originalCenter = self.center; //Declared as a CGPoint at the top of my TableViewCell } if (recognizer.state == UIGestureRecognizerStateChanged) { //translate the center (aka translate from the center of the cell) CGPoint translation = [recognizer translationInView:self]; self.center = CGPointMake(_originalCenter.x + translation.x, _originalCenter.y); // determine whether the item has been dragged far enough to delete/complete } if (recognizer.state == UIGestureRecognizerStateEnded) { // the frame this cell would have had before being dragged CGRect originalFrame = CGRectMake(0, self.frame.origin.y, self.bounds.origin.x, self.bounds.size.height); [UIView animateWithDuration:0.2 animations:^{ self.frame = originalFrame;} ]; } } ``` The Cells don't move at all though. Not really sure what's going on here