3

I'm wondering if someone knows how to implement the "touch up inside" response when a user pushes down then lifts their finger in the touchesBegan, touchesEnded methods. I know this can be done with UITapGestureRecognizer, but actually I'm trying to make it so that it only works on a quick tap (with UITapGestureRecognizer, if you hold your finger there for a long time, then lift, it still executes). Anyone know how to implement this?

asked Oct 11, 2012 at 0:40

6 Answers 6

3

Using the UILongPressGesturizer is actually a much better solution to mimic all of the functionality of a UIButton (touchUpInside, touchUpOutside, touchDown, etc.):

- (void) longPress:(UILongPressGestureRecognizer *)longPressGestureRecognizer
{
 if (longPressGestureRecognizer.state == UIGestureRecognizerStateBegan || longPressGestureRecognizer.state == UIGestureRecognizerStateChanged)
 {
 CGPoint touchedPoint = [longPressGestureRecognizer locationInView: self];
 if (CGRectContainsPoint(self.bounds, touchedPoint))
 {
 [self addHighlights];
 }
 else
 {
 [self removeHighlights];
 }
 }
 else if (longPressGestureRecognizer.state == UIGestureRecognizerStateEnded)
 {
 if (self.highlightView.superview)
 {
 [self removeHighlights];
 }
 CGPoint touchedPoint = [longPressGestureRecognizer locationInView: self];
 if (CGRectContainsPoint(self.bounds, touchedPoint))
 {
 if ([self.delegate respondsToSelector:@selector(buttonViewDidTouchUpInside:)])
 {
 [self.delegate buttonViewDidTouchUpInside:self];
 }
 }
 }
}
answered Feb 19, 2014 at 4:20
Sign up to request clarification or add additional context in comments.

Comments

3

I'm not sure when it was added, but the property isTouchInside is a life saver for any UIControl derived object (e.g. UIButton).

override func endTracking(_ touch: UITouch?, with event: UIEvent?) {
 super.endTracking(touch, with: event)
 if isTouchInside {
 // Do the thing you want to do
 }
}

Here's the Apple official docs

answered Feb 12, 2019 at 6:21

Comments

2

You can implement touchesBegan and touchesEnded by creating a UIView subclass and implementing it there.

However you can also use a UILongPressGestureRecognizer and achieve the same results.

answered Oct 11, 2012 at 0:44

Comments

2

I did this by putting a timer that gets triggered in touchesBegan. If this timer is still running when touchesEnded gets called, then execute whatever code you wanted to. This gives the effect of touchUpInside.

 -(void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
 {
 NSTimer *tapTimer = [[NSTimer scheduledTimerWithTimeInterval:.15 invocation:nil repeats:NO] retain];
 self.tapTimer = tapTimer;
 [tapTimer release];
 }
 -(void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
 {
 if ([self.tapTimer isValid])
 {
 }
 }
answered Oct 15, 2012 at 23:25

1 Comment

This is really smart and easy to understand.
0

You can create some BOOL variable then in -touchesBegan check what view or whatever you need was touched and set this BOOL variable to YES. After that in -touchesEnded check if this variable is YES and your view or whatever you need was touched that will be your -touchUpInside. And of course set BOOL variable to NO after.

answered Oct 11, 2012 at 1:05

Comments

0

You can add a UTapGestureRecognizer and a UILongPressGestureRecognizer and add dependency using [tap requiresGestureRecognizerToFail:longPress]; (tap and long press being the objects of added recognizers).

This way, the tap will not be detected if long press is fired.

answered Oct 11, 2012 at 2:35

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.