I've a question.. I would like to do my own gesture recognizer with swipe and that you drag (or swipe) down with two fingers but I don't now how..
This is my code of GestureSwipe.h:
#import <UIKit/UIKit.h>
#interface GestureSwipe : UIGestureRecognizer
#property CGPoint startTouchPosition;
#property(nonatomic) NSUInteger numberOfTouchesRequired;
#property(nonatomic) UISwipeGestureRecognizerDirection direction;
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event;
#end
This is my code of GestureSwipe.m:
#define VERT_SWIPE_DRAG_MAX 7
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *aTouch = [touches anyObject];
// startTouchPosition is a property
self.startTouchPosition = [aTouch locationInView:self.view];
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *aTouch = [touches anyObject];
CGPoint currentTouchPosition = [aTouch locationInView:self.view];
// Check if direction of touch is horizontal and long enough
if (fabsf(self.startTouchPosition.y - currentTouchPosition.y) <=
VERT_SWIPE_DRAG_MAX)
{
// If touch appears to be a swipe
if (self.startTouchPosition.y < currentTouchPosition.y) {
[self myProcessDownSwipe:touches withEvent:event];
}
self.startTouchPosition = CGPointZero;
}
}
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
self.startTouchPosition = CGPointZero;
}
-(void)myProcessDownSwipe:(NSSet *)touches withEvent:(UIEvent *)event {
}
How should I do to do swipe down with two fingers?
Then I have other VC where recognize my own gesture:
HelloViewController.m
- (void)viewDidLoad
{
[super viewDidLoad];
//newGesture = [[GestureSwipe alloc] init];
newGesture = [[GestureSwipe alloc] initWithTarget:self action:#selector(showImage:)];
newGesture.numberOfTouchesRequired = 2;
}
In HelloViewController you'd add something like this:
UISwipeGestureRecognizer *recognizer;
recognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(handleSwipe:)];
// Set the acceptable swipe direction and number of touches required to do the gesture
[recognizer setDirection:(UISwipeGestureRecognizerDirectionDown)];
recognizer.numberOfTouchesRequired = 2;
// Add the gesture recogizer to the view
[self.view addGestureRecognizer:recognizer];
Then you would create a custom method (I called my one handleSwipe:, but this can be whatever suits you best) and do what you need to do.
EDIT: So your viewDidLoad method would look like this
- (void)viewDidLoad
{
[super viewDidLoad];
UISwipeGestureRecognizer *recognizer;
recognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(handleSwipe:)];
// Set the acceptable swipe direction and number of touches required to do the gesture
[recognizer setDirection:(UISwipeGestureRecognizerDirectionDown)];
recognizer.numberOfTouchesRequired = 2;
// Add the gesture recogizer to the view
[self.view addGestureRecognizer:recognizer];
}
And the handleSwipe: method could be like this:
-(void)handleSwipe:(id)sender{
// Do something
}
There is no need to create your own recognizer. You can handle this with a standard recognizer and just state how many touches is required.
A good example can be found here: Capture only UIView 2 finger UIPanGestureRecognizer
Related
when i double tap on image then the image will show in complete view and at the same time i have to drag the image from one place to another in the same view.
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
Using the above methods the drag and drop of image is implemented successfully but the UITapGesture is not working now. So, how can I implement both ? ``
By just using UILongPressGrstureRecognizer, it is surprising that it is able to implement tap and drag.
As you just drag first Action will be Tap by default.
You have to:
set the numberOfTapsRequired to 1 to detect the initial tap.
set the minimumDuration something smaller to detect drags quicker without waiting
e.g.:
UILongPressGestureRecognizer *mouseDrag = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(handleDrag:)];
mouseDrag.numberOfTapsRequired=1;
mouseDrag.minimumPressDuration=0.05;
[clickLeft requireGestureRecognizerToFail:mouseDrag];
to handle the drag, you must determine the state to handle it appropriately as a continuous gesture.
For tap gesture you can simply use
UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleTapFrom:)];
[self.imageView addGestureRecognizer:tapGestureRecognizer];
tapGestureRecognizer.delegate = self;
While you tap on image this method invoke
- (void) handleTapFrom: (UITapGestureRecognizer *)recognizer
{
//Code to handle the gesture
}
Did you try to add the simultaneous recognition?
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
return YES;
}
For Single Tap in viewDidLoad method,first set the tapGesture Recognizer
UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleSingleTap)];
singleTap.numberOfTapsRequired = 1;
imageView.userInteractionEnabled = YES;
[imageView addGestureRecognizer:singleTap];
Then method
-(void)handleSingleTap
{
NSLog(#"The single tap happened");
}
Touch Events
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
if (touch.tapCount == 1) {
NSLog(#"The single tap happened now");
}
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
NSLog(#"The tap count is - %lu",(unsigned long)touch.tapCount);
if (touch.tapCount == 1)
{
NSLog(#"The single tap Ended now");
}
}
So, I have a custom gesture recognizer added to a skmap, but the behavior is not consistent but rather weird. At first, both map and my gesture recognizer respond to gesture events.
But after panning or pinch to rotate & zoom, only gesture recognizer responds to gestures. While map does not respond to any gesture like pinch/panning/tap. This I call it a "locked" state.
In this state, map does not respond to anything. Trying to rotate/pinch will "unlock" it. But trying to pan will not. So for example, the sequence is, I pan the map, it follows. Then I pan the map several times, it does not move at all. Then I try to rotate it, the map stays still. Then I pan it the third time, it can follow my gesture again.
So my question is, what is the difference between this two state, what changes happened to the map when I move/try to rotate it.
My code is very simple, just for test purpose. myGestureRecognizer.m :
#import "myGestureRecognizer.h"
#import <MapKit/MapKit.h>
#implementation myGestureRecogniczer
-(id)init;
{
self = [super init];
self.delegate = self;
return self;
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
NSLog(#"Touches Began");
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
NSLog(#"Touches Moved");
}
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
NSLog(#"Touches Canceled");
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
NSLog(#"Touches Ended");
}
#end
And mapViewController.m :
-(void)viewDidLoad
{
[super viewDidLoad];
self.myMapView = [[SKMapView alloc] initWithFrame:CGRectMake( 0.0f, 0.0f, CGRectGetWidth(self.view.frame), CGRectGetHeight(self.view.frame))];
self.myMapView.delegate = self;
self.myMapView.calloutView.delegate = self;
[self.view addSubview:self.myMapView];
myGestureRecogniczer *gestureRecognizer = [[myGestureRecogniczer alloc] init];
[self.myMapView addGestureRecognizer:gestureRecognizer];
}
Any idea how to do this? I have a UIImageView inside of each cell in my UITableView and I want to disable scroll when the user starts touching the UIImageView and then enable it once the user stops dragging their finger on the photo.
I just give my logic.
Add UIPanGestureRecognizer to each cell of UITableView.
UIPanGestureRecognizer* panGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(handlePanFrom:)];
[cell addGestureRecognizer:panGestureRecognizer];
And in method name is handlePanFrom:
- (void)handlePanFrom:(UIPanGestureRecognizer*)recognizer
{
CGPoint translation = [recognizer translationInView:recognizer.view];
CGPoint velocity = [recognizer velocityInView:recognizer.view];
if (recognizer.state == UIGestureRecognizerStateBegan)
{
/// track began
tableView.userInteractionEnabled = NO;
}
else if (recognizer.state == UIGestureRecognizerStateChanged)
{
// track the movement
} else if (recognizer.state == UIGestureRecognizerStateEnded)
{
// final position
tableView.userInteractionEnabled = YES;
}
}
Make sure your UIIMageView must be set as a userInteractionEnabled = YES;. Because by default UIIMageView have to set userInteractionEnabled = NO;.
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
if ([touch.view isKindOfClass:[UIImageView class]]) {
NSLog(#"self.tableView.scrollEnabled = NO");
}
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
if ([touch.view isKindOfClass:[UIImageView class]]) {
NSLog(#"self.tableView.scrollEnabled = YES");
}
}
There are two ways to implement this, either include UITapGestureRecognizer or UIPanGestureRecognizer to your UIImageView and set the target and action where target is your custom UITableViewCell class or include
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
methods in the UIImageView custom class and set the delegate via protocol to your custom UITableViewCell.
for UIGestureRecognizer you can check its state property UIGestureRecognizer Class Reference to know the state with the help of switch
typedef enum {
UIGestureRecognizerStatePossible,
UIGestureRecognizerStateBegan,
UIGestureRecognizerStateChanged,
UIGestureRecognizerStateEnded,
UIGestureRecognizerStateCancelled,
UIGestureRecognizerStateFailed,
UIGestureRecognizerStateRecognized = UIGestureRecognizerStateEnded
}
Finally, by toggling the UITableView's scrollEnabled property to stop and start scrolling where UITableView is a sub class of UIScrollView
I have a customized UIView
#interface EColumn : UIView
I have many instances of this EColumn in it's super view.
How can i detect when the finger hold and moves in the area of this UIView, and when it move out.
I don't mean a tap Gesture, i can detect tap Gesture by using this:
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(taped:)];
[self addGestureRecognizer:tapGesture];
#implementation EColumn
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UIView *view = [self touchedViewWithTouches:touches andEvent:event];
NSLog(#"%#",view);
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
UIView *view = [self touchedViewWithTouches:touches andEvent:event];
NSLog(#"%#",view);
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UIView *view = [self touchedViewWithTouches:touches andEvent:event];
NSLog(#"%#",view);
}
- (UIView *)touchedViewWithTouches:(NSSet *)touches andEvent:(UIEvent *)event
{
UITouch *touch = [[event allTouches] anyObject];
CGPoint touchLocation = [touch locationInView:touch.view];
UIView *touchedView;
for (UIView *view in self.subviews)
{
if(CGRectContainsPoint(view.frame, touchLocation))
{
touchedView = view;
break;
}
}
return touchedView;
}
#end
You can detect the finger hold for specific time with the UILongPressGestureRecognizer . For this, you can also specify minimumPressDuration and numberOfTouchesRequired
UILongPressGestureRecognizer *longPressRecognizer =
[[UILongPressGestureRecognizer alloc]
initWithTarget:self
action:#selector(longPressDetected:)];
longPressRecognizer.minimumPressDuration = 3;
longPressRecognizer.numberOfTouchesRequired = 1;
[self addGestureRecognizer:longPressRecognizer];
For detecting moves, you can use UIPanGestureRecognizer
UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(move:)];
[panRecognizer setMinimumNumberOfTouches:1];
[panRecognizer setMaximumNumberOfTouches:1];
[self addGestureRecognizer:panRecognizer];
As I have CustomView where i want to detect Touch Event like when user do Touch Down/Up and release or visa versa as in this Image.
What I tried
Swipe But in Which i Get only coordinate where user releasing the finger. like tap on X = 100 and releasing on 10 and m getting 10 only.
What i am looking for
Want to get whole coordinate like user tap on X = 100 and release on X = 80 then looking for on every single coordinate changed like 100,99,98,97,96,95,94.......80. equally as finger moving.
Please if anyone have any idea about it or something i forget to do.
Please Review.
Change this to your .h file
#interface ViewController : UIViewController{
CGFloat touchStartPoint;
CGFloat touchOffsetPoint;
CGFloat tempTouchOffsetPoint;
}
#end
And this to your .m file
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
UITouch *touch=[touches anyObject];
touchStartPoint=[touch locationInView:self.view].y;
touchOffsetPoint = 0;
tempTouchOffsetPoint = 0;
// NSLog(#"touchStartPoint = %f",touchStartPoint);
}
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
UITouch *touch=[touches anyObject];
touchOffsetPoint = [touch locationInView:self.view].y - touchStartPoint;
if (touchOffsetPoint>tempTouchOffsetPoint) {
NSLog(#"touch down");
}else{
NSLog(#"touch up");
}
tempTouchOffsetPoint = touchOffsetPoint;
}
Here is how I have done it:
UISwipeGestureRecognizer *swipeGesture = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(handleSwipeGesture:)];
swipeGesture.direction = UISwipeGestureRecognizerDirectionUp|UISwipeGestureRecognizerDirectionDown;
[self.gestureAreaView addGestureRecognizer:swipeGesture];
[swipeGesture release];
-(void)handleSwipeGesture:(UISwipeGestureRecognizer *) sender
{
//Gesture detect - swipe up/down , can't be recognized direction
}
UISwipeGestureRecognizer *swipeGesture = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(handleSwipeGesture:)];
swipeGesture.direction = UISwipeGestureRecognizerDirectionUp;
[self.view addGestureRecognizer:swipeGesture];
[swipeGesture release];
UISwipeGestureRecognizer *swipeGesture2 = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(handleSwipeGesture:)];
swipeGesture2.direction = UISwipeGestureRecognizerDirectionDown;
[self.view addGestureRecognizer:swipeGesture2];
[swipeGesture2 release];
-(void)handleSwipeGesture:(UISwipeGestureRecognizer *) sender
{
//Gesture detect - swipe up/down , can be recognized direction
if(sender.direction == UISwipeGestureRecognizerDirectionUp)
{
}
else if(sender.direction == UISwipeGestureRecognizerDirectionDown)
{
}
}
Hope this helps out
Try this method
// declared somewhere
#property (nonatomic, retain) NSMutableArray *touchPositions;
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[super touchesBegan:touches withEvent:event];
UITouch *touch = [[event allTouches] anyObject];
CGPoint loc = [touch locationInView:self];
[self.touchPositions addObject:[NSValue valueWithCGPoint:loc]];
}