I have set two UITapGestureRecognizers in my xib on a UIImageView. I have also set their IBAction in the associated header file.
For the single tap gesture recognizer, I set taps and touches to 1, state to Enabled, and delayed touches ended to YES in the Attributes inspector.
For the double tap gesture recognizer, I set taps and touches to 2, state to Enabled, cancel touches in view to YES and delay touches ended to YES.
When I double tap on the UIImageView, it only triggers the IBAction method for the single tap. So, I decided to print the imageview.gestureRecognizer and it shows the UITapGestureRecognizer for single tap's state as Ended and the UITapGestureRecognizer for double tap's state as Possible.
I have been stuck on this for a couple hours. I found ways to do it programatically but I was wondering how I can do it by setting it in the xib itself.
Any help would be great! Thank you in advance for your responses!
It's a very good question. If you add gestures to code like this
UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget: self action:#selector(singleTap)];
singleTap.numberOfTapsRequired = 1;
[self.view addGestureRecognizer:singleTap];
UITapGestureRecognizer *doubleTap = [[UITapGestureRecognizer alloc] initWithTarget: self action:#selector(doubleTap)] ;
doubleTap.numberOfTapsRequired = 2;
[self.view addGestureRecognizer:doubleTap];
[singleTap requireGestureRecognizerToFail:doubleTap];
And all works fine because you canceled first gesture here
[singleTap requireGestureRecognizerToFail:doubleTap];
If you add two gestures in xib you always should cancel single tap if there was a double tap. And you always need to use 2 properties for gestures and use
[self.firstGestureProperty requireGestureRecognizerToFail:self.secondGestureOroperty];
For single tap:
For double tap:
Source code:
And everything works fine.
I am trying to add a tap recognizer to a UILabel programmatically. It is not working... I have searched and tried a millions things of stackoverflow, but I can't get it to work...
Here is my current code:
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(more:)];
[self.moreLabel setUserInteractionEnabled:YES];
[self.moreLabel addGestureRecognizer:tap];
- (void)more:(UITapGestureRecognizer *)sender {
NSLog(#"HIT?");
}
It will work if I add it to the top view but I don't want that ;) Any help is appreciated.
Solved using #Savitha comment:
Summary of answer: "The view I was trying to touch wasn't under another view so either using bringToFront or setting it correctly in IB was the answere."
Bring moreLabel to front.
[self.view bringViewToFront:self.moreLabel];
I am developing an app and I want to scroll through different UIViewControllers with a UISwipeGestureRecognizer.
Everything works, but there is one thing where I couldn't find a solution for.
I add the UIGestureRecognizers like this
- (void)viewDidLoad {
[super viewDidLoad];
UISwipeGestureRecognizer *swipeLeft = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(swipeLeft)];
[swipeLeft setDirection:UISwipeGestureRecognizerDirectionLeft];
[self.view addGestureRecognizer:swipeLeft];
UISwipeGestureRecognizer *swipeRight = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(swipeRight)];
[swipeRight setDirection:UISwipeGestureRecognizerDirectionRight];
[self.view addGestureRecognizer:swipeRight];
}
Now I want to know if it is possible to except a part of the self.view where it is possible to swipe to a different view.
I want to do this around a UISwitch.
Can someone please help me?
Best regards,
Lukas Goes
You can use another UIView and add it to self.view. Those UISwipeGestureRecognizer won't work inside that UIView.
Add another UISwipeGestureRecognizer to the switch, and, on your original swipe gesture recognisers, call requireGestureRecognizerToFail: on the switch's new recognizer.
Hope that makes sense, it's such a verbose class... :\
I suggest you to use the delegate method of a gesture recognizer : gestureRecognizer:shouldReceiveTouch:.
In the touch parameter, you have many information, like the position in the screen. You can use this position and test if it is above the switch frame. Return yes or no depending of if you want to trigger the selector associated to the gesture recognizer or not.
I am creating a storyboard app where the view is changed when the user performs swipe gestures. The issue I am having is that when you drag and drop a gesture recognizer onto the view from themain.storyboard file, the gesture is recognized from anywhere inside the UIView. Basically, I need to recognize a gesture that is performed in a specific area on the screen, similar to how you drag down the notification center in IOS 6. If this is unclear or you need more details, feel free to ask.
Thanks in advance for any help!
I am not sure if this will help you or you tried something like this, but i want to share my idea.
You can try UISwipeGestureRecognizer in your ViewControl.m like below:
UISwipeGestureRecognizer *swipeGesture = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(swipeToDoMethod)];
[swipeGesture setDirection:UISwipeGestureRecognizerDirectionRight];
[[self innerView] addGestureRecognizer: swipeGesture];
You can add an inner view into your main view and add this gesture to that view.
Hope this helps you, good luck! :)
UISwipeGestureRecognizer *swipe = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(SwipeView)];
[swipe setDirection:UISwipeGestureRecognizerDirectionLeft];
[[self innerView] addGestureRecognizer: swipe];
//UISwipeGestureRecognizerDirectionRight (or) up (or) down
Use another UIView with 0 visibility, put it on area where you want recognize a gesture and then add gesture to this UIView.
This is just an idea.
Hope this will help you.
You can add a subview into your view, set the subview's frame to the area where you want to catch the swipe gesture, add recognizer to it, and set its background color to clear color. Hope it help.
Adding Swift version:
//Add gesture recognizer
let swipeGesture = UISwipeGestureRecognizer(target: self, action: #selector(dismissShowMessageAndButtonDueToSwipeUp))
swipeGesture.direction = .up
backgroundView.addGestureRecognizer(swipeGesture)
I have placed an image (UIImageView) on the navigation bar. Now I want to detect the touch event and want to handle the event. How can I do that?
In practical terms, don't do that.
Instead add a button with Custom style (no button graphics unless you specify images) over the UIImageView. Then attach whatever methods you want called to that.
You can use that technique for many cases where you really want some area of the screen to act as a button instead of messing with the Touch stuff.
A UIImageView is derived from a UIView which is derived from UIResponder so it's ready to handle touch events. You'll want to provide the touchesBegan, touchesMoved, and touchesEnded methods and they'll get called if the user taps the image. If all you want is a tap event, it's easier to just use a custom button with the image set as the button image. But if you want finer-grain control over taps, moves, etc. this is the way to go.
You'll also want to look at a few more things:
Override canBecomeFirstResponder and return YES to indicate that the view can become the focus of touch events (the default is NO).
Set the userInteractionEnabled property to YES. The default for UIViews is YES, but for UIImageViews is NO so you have to explicitly turn it on.
If you want to respond to multi-touch events (i.e. pinch, zoom, etc) you'll want to set multipleTouchEnabled to YES.
To add a touch event to a UIImageView, use the following in your .m file:
UITapGestureRecognizer *newTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(myTapMethod)];
[myImageView setUserInteractionEnabled:YES];
[myImageView addGestureRecognizer:newTap];
-(void)myTapMethod{
// Treat image tap
}
You can also add a UIGestureRecognizer. It does not require you to add an additional element in your view hierarchy, but still provides you will all the nicely written code for handling touch events with a fairly simple interface:
UISwipeGestureRecognizer *swipeRight = [[UISwipeGestureRecognizer alloc]
initWithTarget:self action:#selector(handleSwipe:)];
swipeRight.direction = UISwipeGestureRecognizerDirectionRight;
[imgView_ addGestureRecognizer:swipeRight];
[swipeRight release];
UISwipeGestureRecognizer *swipeLeft = [[UISwipeGestureRecognizer alloc]
initWithTarget:self action:#selector(handleSwipe:)];
swipeLeft.direction = UISwipeGestureRecognizerDirectionLeft;
[imgView_ addGestureRecognizer:swipeLeft];
[swipeLeft release];
I've been on different threads on the past few hours trying to find a solution for my problem, to no avail. I see that many developers share this problem, and I think people here know about this. I have multiple images inside a UIScrollView, trying to get tap events on them.
I am not getting any events from an UIImangeView, but I do get an event from a similar UILable with very similar parameters I am setting to it. Under iOS 5.1.
I have already done the following:
set setUserInteractionEnabled to YES for both `UIImageView and parent
view .
set setMultipleTouchEnabled to YES for UIImageView.
Tried subclassing UIImageView, didn't help any.
Attaching some code below, in this code I initialize both a UIImageView and UILabel, the label works fine in terms of firing events. I tried keeping out irrelevant code.
UIImageView *single_view = [[UIImageView alloc]initWithFrame:CGRectMake(200, 200, 100, 100)];
single_view.image = img;
single_view.layer.zPosition = 4;
UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(singleTapGestureCaptured:)];
[single_view addGestureRecognizer:singleTap];
[single_view setMultipleTouchEnabled:YES];
[single_view setUserInteractionEnabled:YES];
[self.myScrollView addSubview:single_view];
self.myScrollView.userInteractionEnabled = YES;
UILabel *testLabel = [[UILabel alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];
testLabel.backgroundColor = [UIColor redColor];
[self.myScrollView addSubview:testLabel];
[testLabel addGestureRecognizer:singleTap];
[testLabel setMultipleTouchEnabled:YES];
[testLabel setUserInteractionEnabled:YES];
testLabel.layer.zPosition = 4;
And the method which handles the event:
- (void)singleTapGestureCaptured:(UITapGestureRecognizer *)gesture
{
UIView *tappedView = [gesture.view hitTest:[gesture locationInView:gesture.view] withEvent:nil];
NSLog(#"Touch event on view: %#", [tappedView class]);
}
As said, the label tap is received.
Instead of making a touchable UIImageView then placing it on the navbar, you should just create a UIBarButtonItem, which you make out of a UIImageView.
First make the image view:
UIImageView *yourImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"nameOfYourImage.png"]];
Then make the barbutton item out of your image view:
UIBarButtonItem *yourBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:yourImageView];
Then add the bar button item to your navigation bar:
self.navigationItem.rightBarButtonItem = yourBarButtonItem;
Remember that this code goes into the view controller which is inside a navigation controller viewcontroller array. So basically, this "touchable image-looking bar button item" will only appear in the navigation bar when this view controller when it's being shown. When you push another view controller, this navigation bar button item will disappear.
You might want to override the touchesBegan:withEvent: method of the UIView (or subclass) that contains your UIImageView subview.
Within this method, test if any of the UITouch touches fall inside the bounds of the UIImageView instance (let's say it is called imageView).
That is, does the CGPoint element [touch locationInView] intersect with with the CGRect element [imageView bounds]? Look into the function CGRectContainsPoint to run this test.
First, you should place an UIButton and then either you can add a background image for this button, or you need to place an UIImageView over the button.
Or:
You can add the tap gesture to a UIImageView so that get the click action when tap on the UIImageView.
For those of you looking for a Swift 4 solution to this answer, you can use the following to detect a touch event on a UIImageView.
let gestureRecognizer: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(imageViewTapped))
imageView.addGestureRecognizer(gestureRecognizer)
imageView.isUserInteractionEnabled = true
You will then need to define your selector as follows:
#objc func imageViewTapped() {
// Image has been tapped
}
Add gesture on that view. Add an image into that view, and then it would be detecting a gesture on the image too. You could try with the delegate method of the touch event. Then in that case it also might be detecting.