0

My app consists of a deck of cards. Most cards in the deck are made in draggableView. I'm trying to make it so that a double tap on the screen will make my buttons on the card disappear/reappear. After reading this post, I tried to give it shot. I put a UITapGesture into my initWithFrame method in my draggableView class, like so:

- (id)initWithFrame:(CGRect)frame
self = [super initWithFrame:frame];
if (self) {
    [self addSubviewFromNib];
    [self setupView];
    panGestureRecognizer = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(beingDragged:)];
    cardWidth = frame.size.width;
    cardHeight = frame.size.height;
    type = 0;
    panGestureRecognizer.delegate = self;
    panGestureRecognizer.cancelsTouchesInView = NO;
    _backgroundScrollView.panGestureRecognizer.cancelsTouchesInView = NO;
    //...more code above....
    _backgroundScrollView.userInteractionEnabled = YES;
    tapGestureRecognizer = [[UITapGestureRecognizer alloc]   initWithTarget:_backgroundScrollView action:@selector(doubleTap)];
    tapGestureRecognizer.delegate = _backgroundScrollView;
    tapGestureRecognizer.numberOfTapsRequired = 2;
[_backgroundScrollView addGestureRecognizer:tapGestureRecognizer];
[self addGestureRecognizer:panGestureRecognizer];

}

 - (void) doubleTap: (UITapGestureRecognizer *)tapGesturerecognizer{

    _mapButton.hidden = !_mapButton.hidden;
    _menuButton.hidden = !_menuButton.hidden;
    _phoneButton.hidden = !_phoneButton.hidden;
    reviewButton.hidden = !reviewButton.hidden;
    _shareButton.hidden = !_shareButton.hidden;

}


- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldBeRequiredToFailByGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {

    // If the gesture recognizer is a UITapGestureRecongizer, but the other
    // gesture detected is a UIPanGestureRecognizer, require the
    // UITapGestureRecognizer to fail.
    if ([gestureRecognizer isKindOfClass:[UITapGestureRecognizer class]] &&
        [otherGestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]]) {
        return YES;
    } else {
        return NO;
    }
}



- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
{
    if ([gestureRecognizer isKindOfClass:[UITapGestureRecognizer class]]) {
        return YES;
    }
    if ([gestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]]) {
        UIPanGestureRecognizer *panGesture = (UIPanGestureRecognizer *)gestureRecognizer;
        CGPoint velocity = [panGesture velocityInView:self];
        return fabs(velocity.y) <= fabs(velocity.x);
    }
    return YES;
}

However, if I double tap, I get this sib abrt error:

 -[UITapGestureRecognizer velocityInView:]: unrecognized selector sent to instance 0x7f9f9a244230
 *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UITapGestureRecognizer velocityInView:]: unrecognized selector sent to instance 0x7f9f9a244230'

I'm assuming this means there's an error between the PanGestureRecognizer and the TapGesture Recognizer. How do I resolve it?

EDIT: Still unresolved, but if I change the tapGesture to be added to draggable view(thus, self), rather than _backgroundScrollView, I get this error:

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[DraggableView doubleTap]: unrecognized selector sent to instance 0x7fefdd9e4f70'

OTHER EDIT: I changed it back to backgroundScrollView, and I now get this as the error:

[UIScrollView doubleTap]: unrecognized selector sent to instance 0x7fe5130af000
Community
  • 1
  • 1
maddie
  • 1,854
  • 4
  • 30
  • 66
  • post the code related to pan gesture too. Also please post the correct code, you are missing a closing brace in the posted code. – Teja Nandamuri Aug 08 '16 at 17:30
  • Updated it with more code – maddie Aug 08 '16 at 17:44
  • gestureRecognizerShouldBegin will get called, whenver the gesture recogniser is about to procss the touches, it could be either tap gesture or it could be either pan gesture. YOu need to check the gestureRecogniser type and then proceed further, – Teja Nandamuri Aug 08 '16 at 17:49
  • Possible duplicate of [How to compare the types of gestures on iOS?](http://stackoverflow.com/questions/27475250/how-to-compare-the-types-of-gestures-on-ios) – Teja Nandamuri Aug 08 '16 at 17:52
  • I tried the solution offered in that thread, but still got the same sig abrt error :/ – maddie Aug 08 '16 at 18:11
  • You need to change the gestureRecognizerShouldBegin as suggested in that answer. – Teja Nandamuri Aug 08 '16 at 18:32
  • So, I implemented gestureRecognizerShouldBegin as: - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer shouldBeRequiredToFailByGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer { if ([gestureRecognizer isKindOfClass:[UITapGestureRecognizer class]] && [otherGestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]]) { return YES; } else { return NO; } } still getting the same error – maddie Aug 08 '16 at 18:49

2 Answers2

0

gestureRecognizerShouldBegin will get called, whenver the gesture recogniser is about to procss the touches, it could be either tap gesture or it could be either pan gesture. YOu need to check the gestureRecogniser type and then proceed further.

Implement the following method(taken from here) to allow simultaneous gestures to be recognised:

 - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldBeRequiredToFailByGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {

    // If the gesture recognizer is a UITapGestureRecongizer, but the other
    // gesture detected is a UIPanGestureRecognizer, require the
    // UIPanGestureRecognizer to fail.
    if ([gestureRecognizer isKindOfClass:[UITapGestureRecognizer class]] &&
        [otherGestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]])  {
       return YES;
    } else {
       return NO;
    }
}

and in the other delegate method, the crash reason tells you that:

-[UITapGestureRecognizer velocityInView:]: unrecognized selector sent to instance 0x7f9f9a2

velocityInView is being called on wrong gesture type, to avoid these kind of errors, modify your delegate method as below:

- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer 
{
  if ([gestureRecognizer isKindOfClass:[UITapGestureRecognizer class]]) {     
       return YES;
  }
  if ([gestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]]) { 
       UIPanGestureRecogniser *panGesture = (UIPanGestureRecongiser *)gestureRecogniser;    
       CGPoint velocity = [panGesture velocityInView:self];
       return fabs(velocity.y) <= fabs(velocity.x);
  }
   return YES;
}
Community
  • 1
  • 1
Teja Nandamuri
  • 11,045
  • 6
  • 57
  • 109
  • i implemented gestureRecognizer:(changing UILongPressGestureRecognizer to UIPanGestureRecognizer) and gestureRecognizerShouldBegin, but still get the same error :/ – maddie Aug 08 '16 at 19:03
  • did u change the gestureRecognizerShouldBegin as per my answer ? – Teja Nandamuri Aug 08 '16 at 19:06
  • Yeah, I changed that to what you gave above -- still same error – maddie Aug 08 '16 at 19:13
  • okay, please update your question with what you tried just now, and we will see what is wrong. – Teja Nandamuri Aug 08 '16 at 19:19
  • I updated the gestureRecognizerShouldBegin method. Please try it. @MaddieElizabeth – Teja Nandamuri Aug 08 '16 at 20:03
  • Now I'm getting the error, "[UIScrollView doubleTap]: unrecognized selector sent to instance" -- any suggestions? If UIScrollView is the delegate for tapGesture, shouldn't it be able to handle doubleTap? – maddie Aug 09 '16 at 14:52
  • change action:@selector(doubleTap) to action:@selector(doubleTap:). ALso make sure you are not calling doubleTap on scrollView instance. – Teja Nandamuri Aug 09 '16 at 14:57
  • Where is it possible that I'm calling doubleTap on a scrollview instance? I want to change that but I'm so new, I'm lost as to where that could be happening/where I should look. I don't see doubleTap being directly called anywhere in the code. – maddie Aug 09 '16 at 15:09
  • search for the doubleTap in your class. And find out if there is another occurence other than the initWithFrame method. – Teja Nandamuri Aug 09 '16 at 15:10
  • There's not, just the one occurance in initWithFrame – maddie Aug 09 '16 at 15:20
0

My error: in my h file, I needed to use draggableView as the delegate for tapGesture and then insert gestureRecognizer into UIGestureRecognizerDelegate protocol, like so:

@protocol UIGestureRecognizerDelegate <NSObject>
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer;
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldBeRequiredToFailByGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer;
@end
maddie
  • 1,854
  • 4
  • 30
  • 66