Objective-c: How to detect double tap on view? - iphone

I am developing an application where I have multiple controls on view but I want to enable them when user double tap the view
You can take the example of double click but in device I want to catch the event when their is double tap.

You need to add an UITapGestureRecognizer to the view which you want to be tapped.
Like this:
- (void)viewDidLoad {
[super viewDidLoad];
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleTapGesture:)];
tapGesture.numberOfTapsRequired = 2;
[self.view addGestureRecognizer:tapGesture];
[tapGesture release];
}
- (void)handleTapGesture:(UITapGestureRecognizer *)sender {
if (sender.state == UIGestureRecognizerStateRecognized) {
// handling code
}
}

Add a UITapGestureRecognizer to the view, with numberOfTapsRequired = 2.

Related

How do I detect a tap anywhere in the view?

I have a tutorial for my app, which should display only the first time the app is opened and should be tapped to dismiss.
I am initializing a UITapGestureRecognizer in my viewDidLoad:
tapper_tut = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleSingleTap:)];
tapper_tut.cancelsTouchesInView = FALSE;
[self.view addGestureRecognizer:tapper_tut];
and I have an IBAction to detect the tap and set the tutorial to hidden:
- (IBAction)dismiss_tut{
if (????????????????) {
_tutorial.hidden = YES;
}
}
But I have no idea what to put in the if statement condition, or if this is even that right way to go about this.
How would I dismiss a UIImageView on a tap?
UITapGestureRecognizer *gr = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleGesture:)];
[self.view addGestureRecognizer:gr];
// if not using ARC, you should [gr release];
// mySensitiveRect coords are in the coordinate system of self.view
- (void)handleGesture:(UIGestureRecognizer *)gestureRecognizer {
CGPoint p = [gestureRecognizer locationInView:self.view];
if (CGRectContainsPoint(mySensitiveRect, p)) {
NSLog(#"got a tap in the region i care about");
} else {
NSLog(#"got a tap, but not where i need it");
}
}
You can make viewDidLoad like this
- (void)viewDidLoad
{
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];
/* Create the Tap Gesture Recognizer */
self.tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self
action:#selector(handleTaps:)];
/* The number of fingers that must be on the screen */
self.tapGestureRecognizer.numberOfTouchesRequired = 1;
/* The total number of taps to be performed before the gesture is recognized */
self.tapGestureRecognizer.numberOfTapsRequired = 1;
/* Add this gesture recognizer to the view */
[self.view addGestureRecognizer:self.tapGestureRecognizer];
}
To detect the taps you can make the method like this.
- (void) handleTaps:(UITapGestureRecognizer*)paramSender
{
NSUInteger touchCounter = 0;
for (touchCounter = 0;touchCounter < paramSender.numberOfTouchesRequired;touchCounter++)
{
CGPoint touchPoint =[paramSender locationOfTouch:touchCounter inView:paramSender.view];
NSLog(#"Touch #%lu: %#",(unsigned long)touchCounter+1, NSStringFromCGPoint(touchPoint));
}
}
you have to declare .h file as "UIGestureRecognizerDelegate"
you have getting tap of gesture as two way as given below steps.
1) Call delegate method of GestureRecognizer (not given action )
UITapGestureRecognizer *recognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:nil]; // not given action.
recognizer.numberOfTouchesRequired=1;// here how many tap you want set it
[self.view addGestureRecognizer:recognizer];
recognizer.delegate = self;
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
{
//whatever you want write code here
return NO;
}
2) given action
UITapGestureRecognizer *oneTouch=[[UITapGestureRecognizer alloc]initWithTarget:self action:#selector(Addphoto)];
[oneTouch setNumberOfTouchesRequired:1];
[self.view addGestureRecognizer:oneTouch];
-(IBAction)Addphoto
{
//whatever you want write code here
}
may be it will help .
I think u need to detect the first time launch of the application which u can do with following
![[NSUserDefaults standardUserDefaults] boolForKey:#"HasLaunchedOnce"]
Put this in your if statement .

Why are my regular clicks being picked up as LongPresses?

This code worked up until I converted my project from ios4 to ios6 (+ARC) and swapped my xib files for storyboards. Now any click I make is counted as a long press.
Gesture setup
- (void)viewDidLoad
{
[super viewDidLoad];
for(UIButton *button in buttons)
{
UILongPressGestureRecognizer *longPressRecognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(longPressDetected:)];
longPressRecognizer.minimumPressDuration = 1;
longPressRecognizer.numberOfTouchesRequired = 1;
[button addGestureRecognizer:longPressRecognizer];
}
}
LongPress Method
- (IBAction)longPressDetected:(UIGestureRecognizer *)sender
{
if (sender.state != UIGestureRecognizerStateBegan)
{
NSLog(#"duplicate press cancelled");
return;
}
NSLog(#"LongPress Received");
}
Storyboard
As per the screenshot you have added, you have linked the buttons to longPressDetected: in storyboard. You need to remove it in storyboard and it will work fine.
Basically it was executing the button action which was also pointing to the same method.
replace your code to this and then check:
UILongPressGestureRecognizer *longPressRecognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(longPressDetected:)];
longPressRecognizer.minimumPressDuration = 2.0;
longPressRecognizer.delegate = self;
[button addGestureRecognizer:longPressRecognizer];

handle tap click on the background iphone

I have a view which contains different textfield.
Clicking on each taxtfield brings up a keyboard and if I click outside the textField the keyboard disappears but the view is also disappear! how can I change the code so that i can only get out of the view using cancel button and tapping down the view not clicking outside of the texfield or by clicking on the background.
- (void)viewDidLoad
{
[super viewDidLoad];
[self.navigationController setNavigationBarHidden:YES];
self.view.backgroundColor = [self.appDel.styleManager appBackgroundGradientWithFrame:self.view.bounds];
self.tapView.backgroundColor = [UIColor clearColor];
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self
action:#selector(endPageEdit:)];
tap.delegate = self;
[self.view addGestureRecognizer:tap];
}
- (void)endPageEdit:(UIGestureRecognizer *)sender
{
if (sender.view == self.view) {
[self.view endEditing:YES];
if ([self isFormVisible]) {
[self handleTap:sender];
}
}
}
In your endPageEdit: method, tell the textFields to resignFirstResponder.
- (void)endPageEdit:(UIGestureRecognizer *)sender {
// assumes you have an outlet set up for each of the textFields
[self.textFieldA resignFirstResponder];
[self.textFieldB resignFirstResponder];
if (sender.view == self.view) {
[self.view endEditing:YES];
if ([self isFormVisible]) {
[self handleTap:sender];
}
}
}
Only zero or one of them will be the first responder, but there's no downside to resigning first responder when the control is not first responder. The reason the view is disappearing must have something to do with the endEditing: method or the handleTap method which you did not post.

Two finger swipe in UIScrollview for iPad application

Actually i want to implement swipe left and right in UIScrollview. i have scrollview with content size (768,1500). i have tried this but problem is that sometimes its not detecting swipe and perform scrolling there. so now i want to disable scrolling on 2 finger touch.
swipeGesture = [[[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(nextswipedScreen:)] autorelease];
swipeGesture.numberOfTouchesRequired=2;
swipeGesture.direction = UISwipeGestureRecognizerDirectionLeft;
[self addGestureRecognizer:swipeGesture];
swipeGesture = [[[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(previousswipedScreen:)] autorelease];
swipeGesture.numberOfTouchesRequired=2;
swipeGesture.direction = UISwipeGestureRecognizerDirectionRight;
[self addGestureRecognizer:swipeGesture];
i have tried custom scrollview for that but i have problem with touchesBegan method. its not calling every time. even i tried this but not able to stop two finger scroll in UIScrollview.
for (UIGestureRecognizer *mgestureRecognizer in _scrollView.gestureRecognizers) {
if ([mgestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]])
{
UIPanGestureRecognizer *mpanGR = (UIPanGestureRecognizer *) mgestureRecognizer;
mpanGR.minimumNumberOfTouches = 1;
mpanGR.maximumNumberOfTouches = 1;
}
}
Let me know if you have any solution or alternative for that.
I had the same problem; I needed to disable two-finger scrolling so that I could detect a two-finger swipe to the left or right. Here's what I did to set up my scroll view:
- (void) setUpGestureHandlersOnScrollView:(UIScrollView *)scrollView {
// set up a two-finger pan recognizer as a dummy to steal two-finger scrolls from the scroll view
// we initialize without a target or action because we don't want the two-finger pan to be handled
UIPanGestureRecognizer *twoFingerPan = [[UIPanGestureRecognizer alloc] init];
twoFingerPan.minimumNumberOfTouches = 2;
twoFingerPan.maximumNumberOfTouches = 2;
[scrollView addGestureRecognizer:twoFingerPan];
// set up the two-finger left and right swipe recognizers
UISwipeGestureRecognizer *twoFingerSwipeLeft = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(handleGestureFrom:)];
twoFingerSwipeLeft.direction = UISwipeGestureRecognizerDirectionLeft;
twoFingerSwipeLeft.numberOfTouchesRequired = 2;
[scrollView addGestureRecognizer:twoFingerSwipeLeft];
UISwipeGestureRecognizer *twoFingerSwipeRight = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(handleGestureFrom:)];
twoFingerSwipeRight.direction = UISwipeGestureRecognizerDirectionRight;
twoFingerSwipeRight.numberOfTouchesRequired = 2;
[scrollView addGestureRecognizer:twoFingerSwipeRight];
// prevent the two-finger pan recognizer from stealing the two-finger swipe gestures
// this is essential for the swipe recognizers to work
[twoFingerPan requireGestureRecognizerToFail:twoFingerSwipeLeft];
[twoFingerPan requireGestureRecognizerToFail:twoFingerSwipeRight];
}
The handler method should look something like this:
- (void)handleGestureFrom:(UISwipeGestureRecognizer *)recognizer {
if ([recognizer numberOfTouches] == 2) {
// do whatever you need to do
}
}
You can create two gesture recognizers, one for single tap and one for double tap:
UITapGestureRecognizer *singleTapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleTouchesOne:)];
singleTapGesture.cancelsTouchesInView = NO;
singleTapGesture.delaysTouchesEnded = NO;
singleTapGesture.numberOfTouchesRequired = 1; // One finger single tap
singleTapGesture.numberOfTapsRequired = 1;
[Scroll_view addGestureRecognizer:singleTapGesture];
[singleTapGesture release];
UITapGestureRecognizer *doubleTapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleTouchesTwo:)];
doubleTapGesture.cancelsTouchesInView = NO;
doubleTapGesture.delaysTouchesEnded = NO;
doubleTapGesture.numberOfTouchesRequired = 1; // One finger double tap
doubleTapGesture.numberOfTapsRequired = 2;
[Scroll_view addGestureRecognizer:doubleTapGesture];
[doubleTapGesture release];
And then, here comes the punch:
[singleTapGesture requireGestureRecognizerToFail : doubleTapGesture];
requireGestureRecognizerToFail Reference
The last line, makes your single tap handler work only if the double tap fails. So, you get both single tap and double tap in your application.
And So you can do like, in "doubleTapGesture" method you just specified the scrollview with content size (0,0), In "singleTapGesture" method you specified the scrollview with content size (768,1500).
Source knowledge

Limit tap gesture to scrollview and not the button placed upon it

I have a scroll view and a button placed over it , When i add a tap gesture recognizer the button does not work. Is there any way of limiting the tap only to scroll view and not to the button, so that the button functions normally.
here is my code
UITapGestureRecognizer* tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tapGesture:)];
tap.numberOfTapsRequired = 1;
tap.numberOfTouchesRequired = 1;
[scroll addGestureRecognizer:tap];
[tap release];
- (void)tapGesture:(UIGestureRecognizer*)gesture{
NSLog(#"scroll tapped");
}
If you do
tap.cancelsTouchesInView = NO;
It will allow button to be pressed. However taps will be detected along with the button press when you press a button. Do avoid this, you will have to subclass UIScrollView and implement the following method –
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
for ( UIView * subview in self.subviews ) {
UIView * hitView = [subview hitTest:point withEvent:event];
if ( hitView )
return hitView;
}
return [super hitTest:point withEvent:event];
}
Implementing the method above pass the touches to the scroll view's subviews.
There is no need to subclass Scrollview. Following code solves the problem easy way. The method gestureRecognizer:shouldReceiveTouch: does the trick.
UITapGestureRecognizer* tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tapGesture:)];
tap.numberOfTapsRequired = 1;
tap.numberOfTouchesRequired = 1;
tap.delegate = self;
tap.cancelsTouchesInView = NO;
[scroll addGestureRecognizer:tap];
[tap release];
-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
if (scroll.superview != nil) {
if ([touch.view isKindOfClass:[UIButton class]])
{
return NO; // ignore the touch
}
}
return YES; // handle the touch
}
- (void)tapGesture:(UIGestureRecognizer*)gesture {
NSLog(#"scroll tapped");
}