I am working on a food app in which each tableViewCell shows different recipes names. When a user taps on a recipe (in a cell), a detailed view will be opened.
I am now trying to implement a swipe gesture for UIImageView which shows different images on swipe. How do I implement that?
UISwipeGestureRecognizer *swipeLeft = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(swipeImage:)];
UISwipeGestureRecognizer *swipeRight = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(swipeImage:)];
// Setting the swipe direction.
[swipeLeft setDirection:UISwipeGestureRecognizerDirectionLeft];
[swipeRight setDirection:UISwipeGestureRecognizerDirectionRight];
// Adding the swipe gesture on image view
[Allimages addGestureRecognizer:swipeLeft];
[Allimages addGestureRecognizer:swipeRight];
- (void)handleSwipe:(UISwipeGestureRecognizer *)swipe{
NSInteger indexPath;
if (indexPath==0) {
if (swipe.direction == UISwipeGestureRecognizerDirectionLeft) {
arrayimage=[[NSMutableArray alloc]initWithObjects:# "BBQ Chicken Pizza.jpg",# "roastchickensteaks.jpg", nil];
swipee = (swipee > 0)? ([arrayimage count]-1):
swipee%[arrayimage count];
Allimages.image=[UIImage imageNamed: [arrayimageobjectAtIndex:indexPath]];
}}
http://i.stack.imgur.com/apDEw.png
http://i.stack.imgur.com/EiURG.png
http://i.stack.imgur.com/1q799.png
Add this
[imageview setUserInteractionEnabled=YES];
create object for swipegesture recognizer class
UISwipeGestureRecognizer *leftSwipe=[[UISwipeGestureRecognizer alloc]initWithTarget:self action:#selector(onSwipe)];
[leftSwipe setDirection:UISwipeGestureRecognizerDirectionLeft];
Add swipeGesture to imageView
[imageView addGestureRecognizer:leftSwipe];
-(void)onSwipe:(UISwipeGestureRecognizer)swipe{
if(swipe.direction == UISwipeGestureRecognizerDirectionLeft)
{
NSLog(#"leftSwipe");
}
}
if you want more information: just check
Gesture recognizer (swipe) on UIImageView
In your detail View Make UserInteractionEnabledt to YES of your imageview.
[imageView setUserInteractionEnabled:YES];
Adding a Swipe Gesture Events
UISwipeGestureRecognizer *swipeLeft = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(handleSwipe:)];
UISwipeGestureRecognizer *swipeRight = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(handleSwipe:)];
// Setting the swipe direction.
[swipeLeft setDirection:UISwipeGestureRecognizerDirectionLeft];
[swipeRight setDirection:UISwipeGestureRecognizerDirectionRight];
// Adding the swipe gesture on image view
[imageView addGestureRecognizer:swipeLeft];
[imageView addGestureRecognizer:swipeRight];
And Handle Swipe Gesture Events using below code.
- (void)handleSwipe:(UISwipeGestureRecognizer *)swipe {
if (swipe.direction == UISwipeGestureRecognizerDirectionLeft) {
NSLog(#"Left Swipe");
}
if (swipe.direction == UISwipeGestureRecognizerDirectionRight) {
NSLog(#"Right Swipe");
}
}
Or else You can use Third Party Tool
https://www.cocoacontrols.com/controls/pagedflowview
I am trying to add a gesture recognizer using the following code.
However, the gesture is not getting recognized. Is there something else I have to do in order to make the view controller a delegate of the view--or something to that effect?
I have implemented the UIGestureRecognizerDelegate protocol in the .h file
//in view did load
UISwipeGestureRecognizer *rightRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(rightSwipeHandle:)];
rightRecognizer.direction = UISwipeGestureRecognizerDirectionRight;
[rightRecognizer setNumberOfTouchesRequired:1];
[_myImage addGestureRecognizer:rightRecognizer];
//........towards left Gesture recogniser for swiping.....//
UISwipeGestureRecognizer *leftRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(leftSwipeHandle:)];
leftRecognizer.direction = UISwipeGestureRecognizerDirectionLeft;
[leftRecognizer setNumberOfTouchesRequired:1];
[_myImage addGestureRecognizer:leftRecognizer];
//new methods
- (void)rightSwipeHandle:(UISwipeGestureRecognizer*)gestureRecognizer
{
//Do moving
NSLog(#"Right Swipe performed");//not appearing
}
- (void)leftSwipeHandle:(UISwipeGestureRecognizer*)gestureRecognizer
{
// do moving
NSLog(#"Left Swipe performed");//not appearing
}
1st you need
_myImage.userInteractionEnabled=YES;
then
UISwipeGestureRecognizer *swipeLeft = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(handleSwipe:)];
UISwipeGestureRecognizer *swipeRight = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(handleSwipe:)];
// Setting the swipe direction.
[swipeLeft setDirection:UISwipeGestureRecognizerDirectionLeft];
[swipeRight setDirection:UISwipeGestureRecognizerDirectionRight];
// Adding the swipe gesture on image view
[_myImage addGestureRecognizer:swipeLeft];
[_myImage addGestureRecognizer:swipeRight];
then call method like
- (void)handleSwipe:(UISwipeGestureRecognizer *)swipe {
if (swipe.direction == UISwipeGestureRecognizerDirectionLeft)
{
NSLog(#"Left Swipe");
}
if (swipe.direction == UISwipeGestureRecognizerDirectionRight)
{
NSLog(#"Right Swipe");
}
}
i hope this will work..
You have to enable user interaction of "_myImage" before adding gestures to image view as:
_myImage.userInteractionEnabled = YES;
I am adding a UITapGestureRecognizer to my application to detect a double tap gesture.
UITapGestureRecognizer *tapgr = [[UITapGestureRecognizer alloc]
initWithTarget:self action:#selector(handleTapGesture:)];
tapgr.numberOfTaps = 2;
tapgr.delegate = self;
[_view addGestureRecognizer:tapgr];
[tapgr release];
This is working fine unless I show a tooltip in my application. They are set up like this:
[_view.toolTipView addTarget:self action:#selector(handleTap:) forControlEvents:UIControlEventTouchUpInside];
Before the introduction of my gesture recognizer, these tooltips where clickable and reacted, now they aren't reacting anymore...
How can I make a gesture recognizer and a standard UIControlEventTouchUpInside-Setup work together?
I found a solution:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
if (gestureRecognizer == tapgr) {
return ![touch.view isKindOfClass:[UIControl class]];
}
return YES;
}
This method prevents the GestureRecognizer from being fired when a UIControl (i.e. Button) is pressed.
if you want the _view can respond single tap and Double tap together, you can try this
UITapGestureRecognizer * singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleSingleTap:)];
UITapGestureRecognizer * doubleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleDoubleTap:)];
[doubleTap setNumberOfTapsRequired:2];
//Add this code to disable double tap and only responds to single tap when user tap the _view just once time
[singleTap requireGestureRecognizerToFail:doubleTap];
[self addGestureRecognizer:doubleTap];
[self addGestureRecognizer:singleTap];
[singleTap release];
[doubleTap release];
if you want to use TouchEvent try UIControlEventTouchDownRepeat
[button addTarget:self actionselector(multipleTap:withEvent:) forControlEvents:UIControlEventTouchDownRepeat];
//Try to check wheather is doulbe tap or single tap.
-(IBAction)multipleTap:(id)sender withEvent:(UIEvent*)event {
UITouch* touch = [[event allTouches] anyObject];
if (touch.tapCount == 2) {
// do action.
}
}
You can't do that. I think you should choose another way to implement that.
I am trying to add 2 gestures to a uiimage that pulls a subVIew. One gesture is swipe to open/close. And the other is longpressand hold to open it at a specific height.
longPress.minimumPressDuration = 1;
[imageNavigationSlider addGestureRecognizer:longPress];
UILongPressGestureRecognizer *longPressWall = [[[UILongPressGestureRecognizer alloc]
initWithTarget:self action:#selector(handleLongPressWall:)] autorelease];
longPressWall.minimumPressDuration = 1;
PullMeImage.userInteractionEnabled=YES;
[PullMeImage addGestureRecognizer:longPressWall];
UISwipeGestureRecognizer *swipe = [[[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(swipe:)] autorelease];
swipe.direction = UISwipeGestureRecognizerDirectionLeft | UISwipeGestureRecognizerDirectionRight;
[PullMeImage addGestureRecognizer:swipe];
[swipe setDelegate:self];
The long press gesture is correctly recognized, but the swipe isn't.
I also tried using:
-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
return YES;
}
But with no success. Any help will be very much appreciated.
Thank you
I want to add simple swipe gesture recognition to my view based iPhone project. Gestures in all directions (right, down, left, up) should be recognized.
It is stated in the docs for UISwipeGestureRecognizer:
You may specify multiple directions by specifying multiple UISwipeGestureRecognizerDirection constants using bitwise-OR operands. The default direction is UISwipeGestureRecognizerDirectionRight.
However for me it doesn't work. When all four directions are OR'ed only left and right swipes are recognized.
- (void)viewDidLoad {
UISwipeGestureRecognizer *recognizer;
recognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(handleSwipeFrom:)];
[recognizer setDirection:(UISwipeGestureRecognizerDirectionRight | UISwipeGestureRecognizerDirectionDown | UISwipeGestureRecognizerDirectionLeft | UISwipeGestureRecognizerDirectionUp)];
[[self view] addGestureRecognizer:recognizer];
[recognizer release];
[super viewDidLoad];
}
-(void)handleSwipeFrom:(UISwipeGestureRecognizer *)recognizer {
NSLog(#"Swipe received.");
}
I fixed this with adding four recognizers to the view but I'm curious to know why didn't it work as advertised in docs?
- (void)viewDidLoad {
UISwipeGestureRecognizer *recognizer;
recognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(handleSwipeFrom:)];
[recognizer setDirection:(UISwipeGestureRecognizerDirectionRight)];
[[self view] addGestureRecognizer:recognizer];
[recognizer release];
recognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(handleSwipeFrom:)];
[recognizer setDirection:(UISwipeGestureRecognizerDirectionUp)];
[[self view] addGestureRecognizer:recognizer];
[recognizer release];
recognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(handleSwipeFrom:)];
[recognizer setDirection:(UISwipeGestureRecognizerDirectionDown)];
[[self view] addGestureRecognizer:recognizer];
[recognizer release];
recognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(handleSwipeFrom:)];
[recognizer setDirection:(UISwipeGestureRecognizerDirectionLeft)];
[[self view] addGestureRecognizer:recognizer];
[recognizer release];
[super viewDidLoad];
}
-(void)handleSwipeFrom:(UISwipeGestureRecognizer *)recognizer {
NSLog(#"Swipe received.");
}
Seems like there is a bug. You can specify the allowed direction(s) as you did. But when you try to access the actual direction that triggered the swipe in the action selector method you still get the bit mask you originally set (for the allowed directions).
This means that checks for the actual direction will always fail when more than 1 direction is allowed.
You can see it for yourself quite easily when you output the value of 'direction' in the selector method (ie -(void)scrollViewSwiped:(UISwipeGestureRecognizer *)recognizer).
Filed a bug report (#8276386) to Apple.
[Update] I got an answer from Apple saying that the behavior works as was intended.
So for example in a table view you can swipe left or right in a table view cell to trigger 'delete' (this would have directions of the swipe gesture set to left and right)
This means that the original workaround is the way it's supposed to be used. The direction property can only be used to get the gestures recognized correctly, but not in the method performed on a successful recognition to compare for the actual direction that triggered the recognition.
I noticed that left/right and up/down gestures work together in pairs, so you only need to specify two gesture recognizers. And the docs do seem to be wrong.
Well that sucks, I solved the problem by adding 2 gestures like Lars mentioned and that worked perfectly...
1) Left/Right
2) Up/Down
UISwipeGestureRecognizer *swipeLeftRight = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(handleGesture:)];
[swipeLeftRight setDirection:(UISwipeGestureRecognizerDirectionRight | UISwipeGestureRecognizerDirectionLeft )];
[self.view addGestureRecognizer:swipeLeftRight];
UISwipeGestureRecognizer *swipeUpDown = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(handleGesture:)];
[swipeUpDown setDirection:(UISwipeGestureRecognizerDirectionUp | UISwipeGestureRecognizerDirectionDown )];
[self.view addGestureRecognizer:swipeUpDown];
UISwipeGestureRecognizer *recognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(didSwipe:)];
[recognizer setDirection:(UISwipeGestureRecognizerDirectionRight)];
[self.view addGestureRecognizer:recognizer];
[recognizer release];
recognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(didSwipe:)];
[recognizer setDirection:(UISwipeGestureRecognizerDirectionLeft)];
[self.view addGestureRecognizer:recognizer];
[recognizer release];
Now this is the didSwipe function
- (void) didSwipe:(UISwipeGestureRecognizer *)recognizer{
if([recognizer direction] == UISwipeGestureRecognizerDirectionLeft){
//Swipe from right to left
//Do your functions here
}else{
//Swipe from left to right
//Do your functions here
}
}
If your using Xcode 4.2 you can add Gesture Recognizers # the storyboard and then link the GUI Gesture Recognizers to IBActions.
You can find the Gesture Recognizers in the Object Library of the Utility Pane (The bottom of the Right pane).
Then its just a matter of Control-dragging to the appropriate action.
If you want it to detect all four directions, you'll need to create four instances, as you did in your work-around.
Here's Why:
The same instance of UISwipeGestureRecognizer that you create is the instance that gets passed to the selector as sender. So if you set it to recognize all four directions, it will return true for sgr.direction == xxx where xxx is any one of the four directions.
Here's an alternative work-around that involves less code (assumes ARC use):
for(int d = UISwipeGestureRecognizerDirectionRight; d <= UISwipeGestureRecognizerDirectionDown; d = d*2) {
UISwipeGestureRecognizer *sgr = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(handleSwipeFrom:)];
sgr.direction = d;
[self.view addGestureRecognizer:sgr];
}
Swift 2.1
I had to use the following
for var x in [
UISwipeGestureRecognizerDirection.Left,
UISwipeGestureRecognizerDirection.Right,
UISwipeGestureRecognizerDirection.Up,
UISwipeGestureRecognizerDirection.Down
] {
let r = UISwipeGestureRecognizer(target: self, action: "swipe:")
r.direction = x
self.view.addGestureRecognizer(r)
}
Here is a code sample for UISwipeGestureRecognizer usage. Note comments.
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
//add gesture recognizer. The 'direction' property of UISwipeGestureRecognizer only sets the allowable directions. It does not return to the user the direction that was actaully swiped. Must set up separate gesture recognizers to handle the specific directions for which I want an outcome.
UISwipeGestureRecognizer *gestureRight;
UISwipeGestureRecognizer *gestureLeft;
gestureRight = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(swipeRight:)];//direction is set by default.
gestureLeft = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(swipeLeft:)];//need to set direction.
[gestureLeft setDirection:(UISwipeGestureRecognizerDirectionLeft)];
//[gesture setNumberOfTouchesRequired:1];//default is 1
[[self view] addGestureRecognizer:gestureRight];//this gets things rolling.
[[self view] addGestureRecognizer:gestureLeft];//this gets things rolling.
}
swipeRight and swipeLeft are methods that you use to perform specific activities based on left or right swiping. For example:
- (void)swipeRight:(UISwipeGestureRecognizer *)gesture
{
NSLog(#"Right Swipe received.");//Lets you know this method was called by gesture recognizer.
NSLog(#"Direction is: %i", gesture.direction);//Lets you know the numeric value of the gesture direction for confirmation (1=right).
//only interested in gesture if gesture state == changed or ended (From Paul Hegarty # standford U
if ((gesture.state == UIGestureRecognizerStateChanged) ||
(gesture.state == UIGestureRecognizerStateEnded)) {
//do something for a right swipe gesture.
}
}
UISwipeGestureRecognizer *Updown=[[UISwipeGestureRecognizer alloc]initWithTarget:self action:#selector(handleGestureNext:)];
Updown.delegate=self;
[Updown setDirection:UISwipeGestureRecognizerDirectionDown | UISwipeGestureRecognizerDirectionUp];
[overLayView addGestureRecognizer:Updown];
UISwipeGestureRecognizer *LeftRight=[[UISwipeGestureRecognizer alloc]initWithTarget:self action:#selector(handleGestureNext:)];
LeftRight.delegate=self;
[LeftRight setDirection:UISwipeGestureRecognizerDirectionLeft | UISwipeGestureRecognizerDirectionRight];
[overLayView addGestureRecognizer:LeftRight];
overLayView.userInteractionEnabled=NO;
-(void)handleGestureNext:(UISwipeGestureRecognizer *)recognizer
{
NSLog(#"Swipe Recevied");
//Left
//Right
//Top
//Bottom
}
hmm, strange, it works perfect for me, I do exactly same thing
think you should try look at
UIGestureRecognizerDelegate method
- (BOOL)gestureRecognizerShouldBegin:(UISwipeGestureRecognizer *)gestureRecognizer {
// also try to look what's wrong with gesture
NSLog(#"should began gesture %#", gestureRecognizer);
return YES;
}
in logs you must see something like:
should began gesture ; target= <(action=actionForUpDownSwipeGestureRecognizer:, target=)>; direction = up,down,left,right>
use this, it should be the bit operation
gesture.direction & UISwipeGestureRecognizerDirectionUp ||
gesture.direction & UISwipeGestureRecognizerDirectionDown
This was driving me crazy. I finally figured out a reliable way to have multiple swipeGestureRecognizers.
It appears there is a bug in iOS if the name of your "action" selector is the same across multiple swipeGestureRecognizers. If you just name them differently, e.g. handleLeftSwipeFrom and handleRightSwipeFrom, everything works.
UISwipeGestureRecognizer *recognizer;
recognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(handleLeftSwipeFrom:)];
[recognizer setDirection:(UISwipeGestureRecognizerDirectionLeft)];
[[self view] addGestureRecognizer:recognizer];
[recognizer release];
recognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(handleRightSwipeFrom:)];
[recognizer setDirection:(UISwipeGestureRecognizerDirectionRight)];
[[self view] addGestureRecognizer:recognizer];
[recognizer release];