Tap gesture added to UIImageView not responding - ios

I want to make UIImageView respond to user tap. I add image views in storyboard, and set tags to them. Then in viewDidLoad:
UIGestureRecognizer *tapGesture = [[UIGestureRecognizer alloc] initWithTarget:self action:#selector(openCourseView:)];
[self.view viewWithTag:IMAGE_VIEW_TERM].userInteractionEnabled = YES;
[self.view viewWithTag:IMAGE_VIEW_1V1].userInteractionEnabled = YES;
[self.view viewWithTag:IMAGE_VIEW_SPECIAL].userInteractionEnabled = YES;
[[self.view viewWithTag:IMAGE_VIEW_TERM] addGestureRecognizer:tapGesture];
[[self.view viewWithTag:IMAGE_VIEW_1V1] addGestureRecognizer:tapGesture];
[[self.view viewWithTag:IMAGE_VIEW_SPECIAL] addGestureRecognizer:tapGesture];
But my response method openCourseView: never called. Then I tried to use IBOutlet to add gesture recognizer to image view, still not responding.
What's the problem?

It was a mistake found by LokeshChowdary.
In my code, UIGestureRecognizer should be UITapGestureRecognizer.

Related

How to set frame for TapGesture Recognizer

I have an imageview and I want to tap on only one side of imageview. Is it possible to set frame for a gesture? Can anyone help with a solution?
Use UIGestureRecognizerDelegate, i think you can get the idea on how to compare:
-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
if ([touch locationInView:yourview].x < somePoint.x) {
return false;
} else {
return true;
}
}
you could overlay a view on top of the imageview and add the tap recognizer to this new view, something like this will make the left hand side of the image tapable
UIView tapView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, imageView.frame.size.width/2, imageView.frame.size.height)];
[imageView addSubView:tapView]
UITapGestureRecognizer *singleFingerTap =
[[UITapGestureRecognizer alloc] initWithTarget:self
action:#selector(handleSingleTap:)];
[tapView addGestureRecognizer:singleFingerTap];
You can simply put UIView on top of your imageView with frame as per your requirement and put tap gesture on that UIView.
You can do this by storyboard / xib or by programmatically.
By programmatically, for example - you want to tap only within the area with width of 50 px of your imageView. For this:
UIView *vw = [[UIView alloc] initWithFrame:CGRectMake(imgView.frame.origin.x, imgView.frame.origin.y, 50, imgView.frame.size.height)];
// add gesture to view
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleTapGesture:)];
tapGesture.numberOfTapsRequired = 2;
[vw addGestureRecognizer:tapGesture];
[imgView addSubview:vw];
now to handle your double tap
-(void)handleTapGesture:(UITapGestureRecognizer *)gesture
{
// handle double tap
}

UITableView doesn't get touches with single gesture recognizer

I have a UIView with a UITextField, UIButton and UITable view. The textfield and button compromise a search bar and the results are then loaded into the table view.
I'd like to make it so they keyboard dismisses. If the user taps something when they are editing the text field. My strategy would be to add a gesture recognizer to the UIView, but then gesture recognizer seems to intercept all the touches from the table view and you |tableView:didSelectCellAtIndexPath:| never gets called. Whats interesting (to me at least) is that the UIButton is still tap-able when the user is editing the field even though the UITableView isn't.
I've tried implementing |gestureRecognizer::shouldRecognizeSimultaneouslyWithGestureRecognizer:| to alway return yes, but that doesn't help. I've also tried setting
singleTapRecognizer.cancelsTouchesInView = NO;
which also doesn't help.
I'm happy with the idea of adding and removing the gesture recognizer when the text field calls |textFieldDidBeginEditing:| and |textFieldDidFinishEditing:|, though this feels messy and it still takes two taps to touch a cell when you're editing the text field (one to dismiss they keyboard and remove the recognizer, and one to tap the cell).
Is there a better way?
Relevant code below:
- (void)loadView {
[super loadView];
self.scrollView = [[UIScrollView alloc] initWithFrame:[UIScreen mainScreen].bounds];
self.scrollView.backgroundColor = [FDEColors viewBackgroundColor];
self.view = self.scrollView;
self.searchField = [[UITextField alloc] initWithFrame:CGRectZero];
self.searchField.placeholder = #"What are you looking for?";
self.searchField.backgroundColor = [FDEColors textFieldBackgroundColor];
self.searchField.clipsToBounds = YES;
self.searchField.layer.borderColor = [[FDEColors buttonColor] CGColor];
self.searchField.layer.borderWidth = 1.f;
self.searchField.returnKeyType = UIReturnKeySearch;
self.searchField.delegate = self;
[self.view addSubview:self.searchField];
self.searchButton = [[UIButton alloc] initWithFrame:CGRectZero];
self.searchButton.backgroundColor = [FDEColors buttonColor];
[self.searchButton setTitle:#"Search" forState:UIControlStateNormal];
[self.searchButton addTarget:self
action:#selector(searchPressed:)
forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:self.searchButton];
self.resultsTableView =
[[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStyleGrouped];
self.resultsTableView.delegate = self;
self.resultsTableView.dataSource = self;
self.resultsTableView.backgroundColor = [FDEColors viewBackgroundColor];
[self.resultsTableView setSeparatorInset:UIEdgeInsetsZero];
self.resultsTableView.layoutMargins = UIEdgeInsetsZero;
[self.resultsTableView registerClass:[FDESearchResultsCell class]
forCellReuseIdentifier:[FDESearchResultsCell reuseIdentifier]];
[self.view addSubview:self.resultsTableView];
self.singleTapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self
action:#selector(dismissKeyboard)];
[self.view addGestureRecognizer:self.singleTapRecognizer];
}
- (void)dismissKeyboard {
[[self view] endEditing:YES];
}
Try implementing the gesture recognizer's delegate method:
- (BOOL) gestureRecognizer:ShouldReceiveRouch:
In this method, check for the touch's location. If it's inside the tableview, return no, so the tableview can receive the touch. Otherwise, return YES and let the recognizer handle the touch.
Edit: As for the button receiving the touch despite the recognizer's existence, as of iOS6 Apple decided to give buttons and some other controls priority when it comes to recognizing gestures. It only applies to antagonizing gestures though, in your case a single tap. If for example you also had a pan recognizer, the recognizer would have precedence, not the button.
Edit 2:
An example implementation of the method mentioned above:
-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
// Determine if the touch is inside the custom subview
if ([touch view] == self.yourTableView){
// If it is, prevent all of the delegate's gesture recognizers
// from receiving the touch
return NO;
}
return YES;
}

Dismiss keyboard when user swipes inside scrollview

I have my label and textfields inside a scrollview.
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(hideKeyboard)];
tapGesture.numberOfTouchesRequired = 1;
tapGesture.cancelsTouchesInView = NO;
[scrollBill addGestureRecognizer:tapGesture];
I can dismiss the keyboard by tapping on the scrollview. But how do I dismiss the keyboard when the user either swipes or taps on the scrollview?
For dismissal on tap, you use a UITapGestureRecognizer, as you already have.
For dismissal on drag you simply set the keyboardDismissalMode of your UIScrollView to UIScrollViewKeyboardDismissModeOnDrag.
Sample code:
scrollBill.keyboardDismissMode = UIScrollViewKeyboardDismissModeOnDrag;
in scrollBill init method, set Delegate:
scrollBill.delegate = self;
implement scrollView delegate, scroll to hideKeyboard
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
[self resignFirstResponder];
}
used this inside a hideKeyboard method
[self.view endEditing:YES];
or
[scrollBill endEditing:YES];
It works properly.

iOS UITapGestureRecognizer and UIWebView

I have a viewcontroller, which contains a web view.
I'd like to add two gesturerocignizers to the viewController's view:
One UITapGestureRecognizer and one UILongPressureGestureRecognizer.
Here's the code:
UILongPressGestureRecognizer *longPressGesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(backToDashboards:)];
UITapGestureRecognizer *doubleTapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(backToDashboards:)];
doubleTapGesture.numberOfTapsRequired = 2;
doubleTapGesture.delegate = self;
[self.view addGestureRecognizer:longPressGesture];
[self.view addGestureRecognizer:doubleTapGesture];
My view hierarchy:
-ViewController
|
|-View (added the gesture recognizers for this view)
|-WebView
I've added the shouldRecognizeSimultaneouslyWithGestureRecognizer method with return YES
But if I long press the screen nothing happens, only if the press' location is on a place where nothing can be scrolled in the webview.
The double tap recognizer doesn't work at all.
Any idea?
Thank you in advance!
I suspect that because your webview is on top of your view, the app doesnt know if you are tapping the webview or self.view. Check out this reply How to detect of tap gesture is from uiwebview or self.view?
try with below code.Where u r adding gester in you code?
below code is working for me.
- (void)viewDidLoad
{
[super viewDidLoad];
UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc]initWithTarget:self action:#selector(handleLongPress:)];
longPress.numberOfTouchesRequired = 2;
[self.view addGestureRecognizer:longPress];
// if u want to add gesture for u webview,
//[self.webview addGestureRecognizer:longPress]
}
-(void)handleLongPress:(UILongPressGestureRecognizer *)gesture
{
}
//You should enable simultaneous gesture recognition
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
return YES;
}

iOS - TapGestureRecognizer - Tap is applicable for the whole screen not for a view

In my app, I have an image and a UITextView.
I have created a UITapGestureRecognizer for both the views but the issue is that wherever I click on the screen, only the method associated with the UITextView gets executed.
Even if I click on the image, only the UITapGestureRecognizer method associated with the UITextView gets executed.
Following is the code I've implemented:
UITapGestureRecognizer *tapGestureRecognizerImage = [[UITapGestureRecognizer alloc] initWithTarget:self
action:#selector(handleTapFromImage:)];
[infobutton addGestureRecognizer:tapGestureRecognizerImage];
[[self view] addGestureRecognizer:tapGestureRecognizerImage];
UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self
action:#selector(handleTapFrom:)];
[messageOne addGestureRecognizer:tapGestureRecognizer];
[[self view] addGestureRecognizer:tapGestureRecognizer];
//The following are the methods associated
- (void) handleTapFrom: (UITapGestureRecognizer *)recognizer {
//Code to handle the gesture
NSLog(#"I am in handleTapFrom method");
}
- (void) handleTapFromImage: (UITapGestureRecognizer *)recognizer {
//Code to handle the gesture
NSLog(#"I am in handleTapFrom Image method");
[self.view makeToast:#"Your verification code does not match. Re-enter your verification code"];
}
I am sure I am missing something here.
The association in storyboard is correct to my knowledge.
Please correct me where I am going wrong
Thanks for your time
You should not add gesture on self.view.
It should get added on the view for which you want to identify tap event.
You are setting both the Tap Gesture Objects on [self view] object.
Also, the UIImageView object, lets call it imageObj, should have userInteractionEnabled = YES.
instead of:
[[self view] addGestureRecognizer:tapGestureRecognizerImage];
you should do:
[imageObj setUserInteractionEnabled:YES];
[imageObj addGestureRecognizer:tapGestureRecognizerImage];
You generally use -addGestureRecognizer: on the object you want your gesture object to work on.
Say you have a UITapGestureRecognizer object called myTapGesture.
Then, to make it work...
on a UILabel *lblSomeObj it will be:
[lblSomeObj addGestureRecognizer:myTapGesture];
on a UIView *vwSomeObj it will be:
[vwSomeObj addGestureRecognizer:myTapGesture];
etc...
Just add the gesture in the respective views and not in self.view.
UITapGestureRecognizer *tapGestureRecognizerImage = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleTapFromImage:)];
[infobutton addGestureRecognizer:tapGestureRecognizerImage];
UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleTapFrom:)];
[messageOne addGestureRecognizer:tapGestureRecognizer];
Add gesture on UIImageView object and make sure that image view userInteractionEnabled is set to YES
imageObj.userInteractionEnabled = YES;
[imageObj addGestureRecognizer:tapGestureRecognizerImage];
You need to include this piece of code:-
[tapGestureRecognizerImage requireGestureRecognizerToFail:tapGestureRecognizer];
[imageObj addGestureRecognizer:tapGestureRecognizerImage];

Resources