Why are my regular clicks being picked up as LongPresses? - iphone

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];

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 .

UIImageView is not Recognizing Second time Gesture

I have implemented UITapGestureRecognizer on UIImageView, It is working on first tap. On First Tap, I am hiding that image and starting animation. Once the animations are completed, i am showing the image again. But After setting setHidden:FALSE, I am not getting the Tap event of that UIImageView.
Following is the code I am using :
- (void)viewDidLoad{
[super viewDidLoad];
defaultDogView= [[UIImageView alloc] initWithFrame:CGRectMake(3, 270, 110, 210)];
[defaultDogView setImage:[UIImage imageNamed:#"dog1.png"]];
defaultDogView.userInteractionEnabled = YES;
[self addGestureRecognizersToPiece:defaultDogView];
[self.view addSubview:defaultDogView];
}
- (void)addGestureRecognizersToPiece:(UIImageView *)piece
{
NSLog(#"in Gesture");
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(singleTapPiece:)];
[tapGesture setDelegate:self];
[piece addGestureRecognizer:tapGesture];
[tapGesture release];
UILongPressGestureRecognizer *longPressGesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(longPressPiece:)];
[piece addGestureRecognizer:longPressGesture];
[longPressGesture release];
NSLog(#"%#", [piece gestureRecognizers]);
}
- (void)singleTapPiece:(UITapGestureRecognizer *)gestureRecognizer
{
NSLog(#"Image Tapped");
/** Hide the default Image and start the animation ***/
[defaultDogView setHidden:TRUE];
/***Animating the Dog***/
[dogArray addObject:[SpriteHelpers setupAnimatedDog:self.view numFrames:69 withFilePrefix:#"dog" withDuration:(12) ofType:#"png" withValue:0]];
dogView = [dogArray objectAtIndex:0];
//[self addGestureRecognizersToPiece:dogView];
[self performSelector:#selector(callBubbleUpdater) withObject:nil afterDelay:5.5];
}
-(void)showDogFrame{
NSLog(#"%#",[defaultDogView gestureRecognizers]);
[defaultDogView setHidden:FALSE];
defaultDogView.userInteractionEnabled = YES;
}
When view is hidden or its alpha component is zero that view won't receive any UIGestureRecognizers.
I can suggest to use next approach if you need to hide some view (let's name it touchableView) but want it to respond to gestures:
Create backgroundView with the same frame as touchableView:
UIView *backgroundView = [[UIView alloc] initWithFrame:touchableView.frame];
Set background color of backgroundView to clearColor:
backgroundView.backgroundColor = [UIColor clearColor];
Reset position of touchableView:
CGRect frame = touchableView.frame;
frame.origin.x = 0;
frame.origin.y = 0;
Disable user interaction of touchableView:
touchableView.userInteractionEnabled = NO;
Add touchableView as subview to backgroundView:
[backgroundView addSubview:touchableView];
Add appropriate gesture recognizers to backgroundView.
Add backgroundView to view that you want.
Now you can hide touchableView but you will still receive gesture recognizers.
I don't test this but I think it should work.
sure
when UIImageView is hidden. it does not receive any touch events
set alpha zero for uiimageview

Detect when user taps the selection indicator in a UIDatePicker?

How can I detect when the user taps the selection indicator in a UIDatePicker?
Without this the user has to scroll to some other date and then back again to pick the date which is displayed under the selection indicator when the date picker slides up.
Thanks a lot,
Stine
UPDATE: This is the only solution I could come up with myself:
UIDatePicker *aDatePicker = [[UIDatePicker alloc] init];
self.datePicker = aDatePicker;
[aDatePicker release];
[self.datePicker addTarget:self action:#selector(datePicked:) forControlEvents:UIControlEventValueChanged];
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(datePicked:)];
[self.datePicker addGestureRecognizer:tap];
[tap release];
Which means that datePicked will be called twice when the user actually rotates the wheel.
UPDATE: The above mentioned solution does not work for UIPickerViews though. I do not know how to achieve the wanted behavior in those cases.
You can do some tweak in this way:-
Conform delegate <UIGestureRecognizerDelegate>in your .h file
UITapGestureRecognizer* gestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(pickerViewTapGestureRecognized:)];
[yourDatePicker addGestureRecognizer:gestureRecognizer];
gestureRecognizer.delegate=self;
gestureRecognizer.numberOfTapsRequired=2;//Whenever you do double tap it will called. So allow user to do double tap on selected date.
//Below is the Delegate method
-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
return YES;
}
//Below method will trigger when do the double tap
-(void)pickerViewTapGestureRecognized:(UITapGestureRecognizer*)recognizer
{
UIDatePicker *datePicker=(UIDatePicker*)[[recognizer view] viewWithTag:101];
NSLog(#"datePicker=%#", datePicker.date);
}
Try this code:
UITapGestureRecognizer *recognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(pickerViewTapped:)];
[recognizer setNumberOfTapsRequired:2];
[recognizer setCancelsTouchesInView:NO];
[recognizer setDelaysTouchesEnded:NO];
[recognizer setDelaysTouchesBegan:NO];
[self.answerPicker addGestureRecognizer:recognizer];
// ....
- (IBAction)pickerViewTapped:(UITapGestureRecognizer *)sender {
CGPoint coord = [sender locationInView:self.answerPicker];
if(coord.y <= 126 && coord.y >= 90) {
//do something
}
}
This is an old question but here's what I did in order to grab the selection bar rect on the UIDatePicker. With this, you could just add a button/view with a gesture recognizer to detect taps. It's a bit of a hack but it seems to be working well in iOS6 and iOS7.
+ (CGRect)getSelectionBarRectFromPicker:(UIDatePicker *)picker
{
int counter = 0;
CGRect selectionBarRect;
for(UIView *datePickerView in picker.subviews){
for(UIView *subview in datePickerView.subviews){
if([[[UIDevice currentDevice] systemVersion] floatValue] < 7.0){
if([NSStringFromClass([subview class]) isEqualToString:#"_UIPickerViewSelectionBar"]){
if(counter == 0){
selectionBarRect.origin = subview.frame.origin;
selectionBarRect.size.height = subview.frame.size.height;
}
selectionBarRect.size.width += subview.frame.size.width;
counter++;
}
} else {
if(subview.frame.size.height < 1){
if(counter == 0){
selectionBarRect.origin = subview.frame.origin;
selectionBarRect.size.width = subview.frame.size.width;
} else {
selectionBarRect.size.height = subview.frame.origin.y - selectionBarRect.origin.y;
}
counter++;
}
}
}
}
return selectionBarRect;
}

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

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.

How do i attached a tap event to a uiwebview?

I am trying to attach a UITapGestureRecognizer to a webview that i am creating and then remove that view when a user taps the webview. Below is my sample code. What am i doing wrong? Thanks!
- (void) setupPuzzle1
{
puzzleDuration--;
//Create object circle
UIImageView *circleView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"red-circle.png"] highlightedImage:[UIImage imageNamed:#"red-circle.png"]];
UITapGestureRecognizer *recognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(removeImage:)];
recognizer.numberOfTapsRequired = 1;
recognizer.numberOfTouchesRequired = 1;
recognizer.delegate = self;
[circleView addGestureRecognizer:recognizer];
[recognizer release];
int x = rand()%280;
int y = rand()%420;
circleView.frame = CGRectMake(x,y,40,40);
[self.view addSubview:circleView];
if (puzzleDuration > 0)
{
[NSTimer scheduledTimerWithTimeInterval:1 target:self selector:#selector(setupPuzzle1) userInfo:nil repeats:NO];
}
}
#pragma mark - UITapGestureRecognizer methods
- (void)removeImage:(UITapGestureRecognizer *)recognizer
{
NSLog(#"Remove Image");
[[recognizer view] removeFromSuperview];
}
#end
I think you weren't talking about UIWebView at all. If you did, your code didn't reflect that. As such you are dealing with UIImageView and the reason is pretty straightforward as any UIImageView object by default has its userInteractionEnabled set to NO. You should change it to YES. So add this line,
circleView.userInteractionEnabled = YES;
and you aren't releasing it either. So add
[circleView release];
after you add it as a subview.