Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to differentiate between a long press and a tap on a button?

Can we call different actions / delegates in response to the two different events of

  1. A tap on a UIButton
  2. A tap-and-hold on a UIButton

?

like image 826
Abhinav Avatar asked Dec 16 '10 19:12

Abhinav


Video Answer


2 Answers

Yes, it's reasonably easy to implement this using a UILongPressGestureRecognizer (on iPhone OS 3.2+). A long press will be handled by the gesture recognizer, and a short tap will pass through to the button's normal action.

For example, I subclassed UIButton and added the following method for specifying a long touch action to go along with a tap (longPressGestureRecognizer is an instance variable):

- (void)setLongTouchAction:(SEL)newValue
{
    if (newValue == NULL)
    {
        [self removeGestureRecognizer:longPressGestureRecognizer];
        [longPressGestureRecognizer release];
        longPressGestureRecognizer = nil;
    }
    else
    {
        [longPressGestureRecognizer release];
        longPressGestureRecognizer = nil;

        longPressGestureRecognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:[[self allTargets] anyObject] action:newValue];
        [self addGestureRecognizer:longPressGestureRecognizer];
    }
}

I then could do the following to set both short tap and long press actions that will be handled by the same target:

[undoButton addTarget:self action:@selector(performUndo:) forControlEvents:UIControlEventTouchUpInside];
[undoButton setLongTouchAction:@selector(showUndoOptions:)];

As you can see, this is useful for the undo buttons you see in title bars of many iPad applications.

like image 118
Brad Larson Avatar answered Nov 15 '22 19:11

Brad Larson


Brad Larson's answer looks pretty good but here's another one that might give you a bit more flexibility/control of what you want or might want to do.

You subclass UIButton, you override the touchesBegan and touchesEnded methods so that when the user starts a touch you call

[self performSelector:@selector(detecetedLongTap) withObject:nil afterDelay:1.0];

and in the touchesEnded you call:

[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(detecetedLongTap) object:nil];

to cancel the event if the finger was lifted too soon.

You can get full code for this in this blog post:

http://www.isignmeout.com/adding-long-tap-functionality-uibutton/

like image 42
shein Avatar answered Nov 15 '22 20:11

shein