IOS: recognize a swipe gesture - ios

In my app I have this code:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)recognizer shouldReceiveTouch:(UITouch *)touch
{
if ([touch.view isKindOfClass:[UIScrollView class]]){
return YES;
}
else return NO;
}
In this I control if my touch is inside a scrollView or not but now I want to check if the touch is a simple touch or is a swipe gesture, is there a way to detect it?
thanks

The method you written above is UIGestureRecognizerDelegate. This is a delegate method will get called when particular gesture on which you put an observer, gets detected.
In order to identify swipe gesture, you have to add Gesture recognizer to View on which you want to detect as below:
UISwipeGestureRecognizer *recognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(handleSwipeFrom:)];
[recognizer setDirection:(UISwipeGestureRecognizerDirectionRight)];
[[self view] addGestureRecognizer:recognizer];
[recognizer release];
You can get gesture detection in method handleSwipeForm:
If you want to get the above delegate to get called then also add this line,
recognizer.delegate = self;

Use UISwipeGestureRecognizer to detect swipe gestures (you can set the swipe direction: UISwipeGestureRecognizer.direction)
And a UITapGestureRecognizer to detect taps (UITapGestureRecognizer.numberOfTapsRequired sets the required number of taps to trigger the recognizer (e. g. for double-taps)

You have to use UISwipeGestureRecognizer in order to detect swipe gestures .
UISwipeGestureRecognizer *swipeGest= [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(SwipeRecognizer:)];
[swipeGest setDirection:(UISwipeGestureRecognizerDirectionRight)];
[[self view] addGestureRecognizer:swipeGest];
swipeGest.delegate = self;
setDirection is used to set the swipe detect direction.
- (void)SwipeRecognizer:(UIGestureRecognizer *)gestureRecognizer
{
}
Here we will be writing the function to do after detecting the swipe gesture.

Related

How to get a CGPoint from a tapped location on a custom View When Voice Over Enabled?

I am setting up my app to be compatible with Voice Over feature. I have a graph, I am getting single tap on the -accessibilitiHint(). I need to confirm the user action on double tap which the even can be obtained with accessibilityActivate(). The touch point needs to be retrieved on Single tap.
Now Is there any method to to get user touch point when single tap is performed on my View ?
For Objective C
Step 1:Add TapeGesture Recognizer to your View
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tapGestureHandler:)];
tapGesture.delegate = self;
[yourView addGestureRecognizer:tapGesture];
Step 2: implement Gesture Delegate Method
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
return YES;
}
Step 3: implement Gesture Handler
- (void)tapGestureHandler:(UITapGestureRecognizer *)gesture
{
CGPoint touchPoint = [gesture locationInView:yourView];
}

tableView is hiding due to a gestureRecognizer before it can execute didSelectRowAtIndexPath

I am trying to handle tableViewCell's being tapped, but the problem is that this is a "temporary tableView". I have it coded so that it will appear while the user is editing a UITextField, but then I set up a gesture recognizer to set the tableview to hidden as soon as the user clicks somewhere away from the UITextField.
I have the gesture recognizer set up as follows:
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]
initWithTarget:self
action:#selector(dismissKeyboard)];
[tap setCancelsTouchesInView:NO];
[self.view addGestureRecognizer:tap];
However, dismissKeyboard is called before didSelectRowAtIndexPath is called, and so the TableView that I want to handle the event on becomes hidden and therefore this function is never called.
My question is: Does anybody have ideas of how to get around this, so that didSelectRowAtIndexPath will execute before the tableView hides? I had one idea to somehow see if the tableView is where the tap is coming from, and if so, then don't execute the "hide tableView" line within dismissKeyboard. Is this possible?
Sorry, but I am new to iOS dev, so thank you for any advice!
You should be able to do this by making your view controller the tap gesture's delegate and denying it any touches that are inside the table view. Here is a starting point:
-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gesture shouldReceiveTouch:(UITouch *)touch
{
//Assuming your table view is a direct subview of the gesture recognizer's view
BOOL isInsideTableView = CGRectContainsPoint(tableView.frame, [touch locationInView:gesture.view])
if (isInsideTableView)
return NO;
return YES;
}
Hope this helps!
You could set yourself as a delegate to the UITapGestureRecognizer and cancel the gesture when the user taps within the tableView.
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
//You can also (and should) check to make sure the gestureRecognizer is the tapGestureRecognizer
if (touch.view == tableView)
{
return NO;
}
else
{
return YES;
}
}
To better fit what you need, judge if your search bar is first responder.
-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gesture shouldReceiveTouch:(UITouch *)touch
{
BOOL isInsideTableView = CGRectContainsPoint(yourTabelView.frame, [touch locationInView:gesture.view]);
if (isInsideTableView && ![yourSearchBar isFirstResponder])
return NO;
return YES;
}

iOS Generic Touch Handler

Is there any such thing as a generic handler for any sort of touch event? A method that get called when any sort of interaction occurs with information about the touch event passed as a parameter.
You are going to want to adhere to the UIGestureRecognizerDelegate protocol, namely the following two methods:
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer;
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch;
Within these methods you can check the gesture recognizer object to see if it is the type of gesture you are looking for and specify whether or not the gesture should begin or receive the touch.
EDIT: To detect the end of a gesture you would have something like this:
// in viewDidLoad or in initialization of your view controller:
_panGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(handlePanGestureRecognizer:)];
[self addGestureRecognizer:_panGestureRecognizer];
[_panGestureRecognizer setDelegate:self];
- (void)handlePanGestureRecognizer:(UIPanGestureRecognizer *)gesture {
UIGestureRecognizerState state = [gesture state];
if (state == UIGestureRecognizerStateEnded) {
// gesture ended here
}
}

How can I tell a custom UIView with UITextField receive touch events

What I'm working with is I have a custom UIView that combines a UILabel with a UITextField as part of some user input. I have several of these throughout the view that is being displayed in the app. What would be good is to be able to have the user touch either the UILabel or the UITextField and then have the UITextField allow for input of the field.
Is there an easy way to do this?
Add a tap gesture recognizer to your label, and when tapped tell the corresponding textfield to become first responder (which brings up the keyboard).
// In your init or awakeFromNib:
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(labelTapped:)];
self.label.userInteractionEnabled = YES;
[self.label addGestureRecognizer:tap];
...
- (void)labelTapped:(id)sender
{
[self.textField becomeFirstResponder];
}
Yes, there is and I actually tested it. You can add a tap gesture recognizer to your view (the one that contains the label and the text view) like so:
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(viewTapped:)];
[self addGestureRecognizer:[tap autorelease]];
and then, inside viewTapped:
-(void)viewTapped:(id)sender {
[self.yourTextField becomeFirstResponder];
}
Hope this helps!
You can define UIGestureRecognizer delegate method and check that is the the required tap gesture area . If it is then return TRUE else return FALSE .
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
// Disallow recognition of tap gestures in the segmented control.
if ((touch.view == yourButton)) {//change it to your condition
return NO;
}
return YES;
}

MKMapView Not Calling regionDidChangeAnimated on Pan

I have an app with a MKMapView and code that is called each time the map changes locations (in regionDidChangeAnimated). When the app initially loads, regionDidChangeAnimated is called on pans (swipes), pinches, taps and buttons that explicitly update the map coordinates. After loading other views and coming back to the map the regionDidChangeAnimated is only called for taps and the buttons that explicitly update the map. Panning the map and pinches no longer call regionDidChangeAnimated.
I have looked at this stackoverflow post which did not solve this issue. The forum posts on devforums and iphonedevsdk also did not work. Does anyone know what causes this issue? I am not adding any subviews to MKMapView.
I did not want to initially do it this way, but it appears to work with no problems so far (taken from devforums post in question):
Add the UIGestureRecognizerDelegate to your header.
Now add a check for the version number... If we're on iOS 4 we can do this:
if (NSFoundationVersionNumber >= 678.58){
UIPinchGestureRecognizer *pinch = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:#selector(pinchGestureCaptured:)];
pinch.delegate = self;
[mapView addGestureRecognizer:pinch];
[pinch release];
UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(panGestureCaptured:)];
pan.delegate = self;
[mapView addGestureRecognizer:pan];
[pan release];
}
Add the delegate methods to handle the gestures:
#pragma mark -
#pragma mark Gesture Recognizers
- (void)pinchGestureCaptured:(UIPinchGestureRecognizer*)gesture{
if(UIGestureRecognizerStateEnded == gesture.state){
///////////////////[self doWhatYouWouldDoInRegionDidChangeAnimated];
}
}
- (void)panGestureCaptured:(UIPanGestureRecognizer*)gesture{
if(UIGestureRecognizerStateEnded == gesture.state){
///////////////////[self doWhatYouWouldDoInRegionDidChangeAnimated];
}
}
-(BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer{
return YES;
}
-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch: (UITouch *)touch{
return YES;
}
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer{
return YES;
}

Resources