UITapGestureRecognizer sender is the gesture, not the ui object
You can get a reference to the view the gesture is added to via its view property. In this case you are adding it to the button so the view property would return you you the button.
let button = sender.view as? UIButton
Referencing a button when the action's sender is a UIGestureRecognizer
The UIGestureRecognizer
class has a view
property representing the view the gesture recognizer is attached to, in your case, the button.
- (void)twoFingerTap:(UIGestureRecognizer *)sender {
UIButton *myButton = (UIButton *)sender.view;
}
tap gesture recognizer - which object was tapped?
Define your target selector(highlightLetter:
) with argument as
UITapGestureRecognizer *letterTapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(highlightLetter:)];
Then you can get view by
- (void)highlightLetter:(UITapGestureRecognizer*)sender {
UIView *view = sender.view;
NSLog(@"%d", view.tag);//By tag, you can find out where you had tapped.
}
UI Tap Gesture Recognizer Not working does not know which View it was tapped
Each View requires its own Gesture Recognizer set. Here is a piece of code that should work for you.
-(void)addTapGesturesToViews
{
int maxViewTag = 6; // tags must be consective (are in your case)
for(int i =1; i<= maxViewTag;i++)
{
UIView * view = [self.view viewWithTag:i];
UITapGestureRecognizer * tapGest = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(colorTapRecognizer:)];
tapGest.numberOfTapsRequired = 1;
[view addGestureRecognizer:tapGest];
}
}
Multiple UITapGestureRecognizer not working on UIScrollView
A tap gesture only has one state - "ended". You can't detect when a tap starts using a tap gesture. As you've seen, attempting to use two tap gestures doesn't accomplish what you want.
You need to implement the UIResponder
methods touchesBegan
and touchesEnded
.
You may also want to see UITapGestureRecognizer - make it work on touch down, not touch up?
.
Gesture recognizer code being called twice after leaving and coming back to view
Move the tap gesture code into viewDidLoad
and not viewDidAppear
let doubleTap = UITapGestureRecognizer(target: self, action: #selector(self.doubleTapAction(sender:)))
doubleTap.numberOfTapsRequired = 2
self.addGestureRecognizer(doubleTap)
viewDidAppear
will be called every time you go back to that screen. You don't need to remove the gesture recognisers when you move to a different screen - they will only be called when that view is visible.
UITapGestureRecognizer tap on self.view but ignore subviews
You should adopt the UIGestureRecognizerDelegate
protocol inside the self
object and call the below method for checking the view. Inside this method, check your view against touch.view
and return the appropriate bool (Yes/No). Something like this:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
if ([touch.view isDescendantOfView:yourSubView]) {
return NO;
}
return YES;
}
Edit: Please, also check @Ian's answer!
Swift 5
// MARK: UIGestureRecognizerDelegate methods, You need to set the delegate of the recognizer
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
if touch.view?.isDescendant(of: tableView) == true {
return false
}
return true
}
Swift UITapGestureRecognizer not calling
The target should be the coordinator
(which is a persistent entity, unlike the transient View), not self
.
let focusGesture = UITapGestureRecognizer(target: context.coordinator, action: #selector(context.coordinator.tapFocus(_:)))
iOS - UITapGestureRecognizer - Selector with Arguments
You're almost there. UIGestureRecognizer has a view property. If you allocate and attach a gesture recognizer to each image view - just as it appears you do in the code snippet - then your gesture code (on the target) can look like this:
- (void) imageTapped:(UITapGestureRecognizer *)gr {
UIImageView *theTappedImageView = (UIImageView *)gr.view;
}
What's less clear from the code you provided is how you associate your Plant model object with it's corresponding imageView, but it could be something like this:
NSArray *myPlants;
for (i=0; i<myPlants.count; i++) {
Plant *myPlant = [myPlants objectAtIndex:i];
UIImage *image = [UIImage imageNamed:myPlant.imageName]; // or however you get an image from a plant
UIImageView *imageView = [[UIImageView alloc] initWithImage:image]; // set frame, etc.
// important bit here...
imageView.tag = i + 32;
[self.view addSubview:imageView];
}
Now the gr code can do this:
- (void) imageTapped:(UITapGestureRecognizer *)gr {
UIImageView *theTappedImageView = (UIImageView *)gr.view;
NSInteger tag = theTappedImageView.tag;
Plant *myPlant = [myPlants objectAtIndex:tag-32];
}
Related Topics
Swift Universal Framework Depending on Pod
Import Xctest into a Dynamic Framework
How to Make an API Call When the User Terminates the App
How to Detect Which Annotation Was Selected in Mapview
Setup a Collectionview with "Tag"-Like Cells
How to Get Label Name from Button
How to Create a CSV File from Core Data (Swift)
How to Crop a 4*3 Image in Photolibrary or Camera in Swift
Rotate a Imageview Around a Pivot Point in iOS
Swift: Load Custom Uiview from Xib Programmatically
How to Convert an Int into Nsdata in Swift
Libmobilegestalt Mobilegestalt.C:890: Mgisdeviceoneoftype Is Not Supported on This Platform
Different Cell in Tableview Swift 3
In Collectionview How to Set Colors According to Selection