UITapGestureRecognizer not doing anything - iphone

I've got an app that displays a page of text with the ability to tap a button or swipe in a view to advance or retreat through various pages. The container view has two UISwipeGestureRecognizers attached, for swipe left and swipe right. No trouble with these gestures. But now I'm trying to add UITapGestureRecognizer to another view, providing an ability similar to iBooks or the Kindle app, tap the left to go back, the right to go forward. Nothing I do can get the gesture to fire. No hint that it is ever being triggered, even if I put the gesture on my topmost view and disable other gestures.
The view controller implements UIGestureRecognizerDelegate, though I've not needed to implement delegate methods. I did try implementing shouldReceiveTouch: without success.
Here's a snippet of code where I create and attach the gesture recognizer:
UITapGestureRecognizer *recognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tapGestureTurnPage:)];
[self.view addGestureRecognizer:recognizer];
[recognizer release];

Try this on the view you're adding the gesture recognizers:
view.userInteractionEnabled = YES;

You mention that you've tried this, but just in case go through it again.
Try using the delegate with <UIGestureRecognizerDelegate> in the header and then setting the delegate:
UITapGestureRecognizer *recognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tapGestureTurnPage:)];
[self.view addGestureRecognizer:recognizer];
recognizer.delegate = self;
[recognizer release];
Then implement this method:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer
shouldReceiveTouch:(UITouch *)touch {
return YES;
}
Then use a debugger or toss an NSLog into the above method and also tapGestureTurnPage: to see if these methods are being called.

Add this where you initialize the gesture:
recognizer.delegate = self;
and add this in the "self" class:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
return YES;
}
This allows me to have gestures recognized on the UIWebView, and the UIWebView will still respond to the taps. (which i wanted - you may not)

Related

How can I supersede the built-in swipe gesture recognizer in UICollectionView?

We're building an app that takes advantage of the new UICollectionView in iOS 6. However, we need to implement a long-press behavior such that even if the user then moves their finger after, we want it ignored.
i.e.
User touches the screen than instantly moves -> Swipe
User touches the screen, pauses, then moves -> Ignore swipe and wait for the release.
Basically, we only want to allow the built-in swipe gesture to be enabled if our gesture recognizer fails. However, we're not sure how to supersede the built-in swipe gesture recognizers with that 'Other recognizer must fail first' logic.
We're not sure if we're allowed to simply walk the chain trying to find the UIScrollView and interrogate that as we don't know if that violates Apple's guidelines, and if I remember correctly, they actually warn against messing with their recognizers anyway.
So how can we create tap-to-hold recognizers that supersede the built in ones?
There's an example on page 36 of the UICollectionView programming guide:
UITapGestureRecognizer* tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleTapGesture:)];
NSArray* recognizers = [self.collectionView gestureRecognizers];
// Make the default gesture recognizer wait until the custom one fails.
for (UIGestureRecognizer* aRecognizer in recognizers) {
if ([aRecognizer isKindOfClass:[UITapGestureRecognizer class]]) {
[aRecognizer requireGestureRecognizerToFail:tapGesture];
}
}
// Now add the gesture recognizer to the collection view.
tapGesture.numberOfTapsRequired = 2;
[self.collectionView addGestureRecognizer:tapGesture];
Original answer
Have a look at UITapGestureRecognizerDelegate, which can be used to allow two gesture recognizers to process touches at once:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
return YES;
}
For more info, see a tutorial such as this:
http://www.raywenderlich.com/6567/uigesturerecognizer-tutorial-in-ios-5-pinches-pans-and-more
Before your new UILongPressGestureRecognizer transnitions from the possible state, he will ask its delegate gestureRecognizerShouldBegin:. You can use that delegate method to cancel (force to failed state) any other gesture recogniser attached to the same view.
You do this by implementing the following as a delegate for your new UILongPressGestureRecognizer:
#implementation DragPictogramGestureRecognizerDelegate
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {
for (UIGestureRecognizer *gr in gestureRecognizer.view.gestureRecognizers) {
if ([gr isKindOfClass:[UILongPressGestureRecognizer class]] == NO) {
gr.enabled = NO;
gr.enabled = YES;
}
}
return YES;
}
#end
Further more, in order to allow the user to use your new UILongPressGestureRecognizer with one finger, and use another finger to scroll the UICollectionView at the same time, you can implement the following delegate in the same class.
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
return YES;
}

How to create Tap event on Long Tap gesture on UIWebView?

I have added Long Tap gesture on UIWebView. But I want UIWebView to process a standard Tap event before my Long Tap will be recognized. (Two gestures should be processed on Long Tap - a simple Tap and my Long Tap). How to do this?
I think it's required to send Tap event to UIWebView on TouchBegin. Is it correct?
The correct code:
- (void)viewDidLoad {
UILongPressGestureRecognizer* gesture = [[[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(handleLongPress:)] autorelease];
gesture.delegate = self;
[myWebView addGestureRecognizer:gesture];
}
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
return YES;
}
Please refer this section UIGestureRecognizerDelegate
http://developer.apple.com/library/ios/#documentation/uikit/reference/UIGestureRecognizerDelegate_Protocol/Reference/Reference.html
you found this is called when 2 gesture simultaneous work.
gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer:

How to make the tableview response pan gesture in ZUUIRevealController

The navigation bar can response the pan gestures in ZUUIRevealController. But I want to make the whole screen of frontViewController response the pan gestures like Path2, so I write code like this:
UIPanGestureRecognizer *recognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self.navigationController.parentViewController action:#selector(revealGesture:)];
[self.view addGestureRecognizer:recognizer];
It works fine except in UITableViewController. When I put it in viewDidLoad method of UITableViewController, the table can not response any other pan gestures, so it can not scroll.
How can I make it work like Path2: pan it horizontally is to reveal, and vertically is to works like normal table view?
There is a simple solution:
in the frontViewController:
- (void)viewDidLoad
{
...
UIPanGestureRecognizer *recognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self.navigationController.parentViewController action:#selector(revealGesture:)];
recognizer.delegate = self;
...
}
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
return TRUE;
}

How to get touch/click on a MPMoviePlayerController view when MPMovieControlStyle = MPMovieControlStyleNone

In one of my application, I don't want to show any video controllers. But I need to get the touch on the media player view. I need to do some other action on touch on the movie player. How can I implement that. Please help
Thanks in advance.
You can always attach a UITapGestureRecognizer to the view and handle the taps.
UITapGestureRecognizer * tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleTap:)];
[moviePlayer.view addGestureRecognizer:tap];
[tap release];
And handle the tap in handleTap:
- (void)handleTap:(UITapGestureRecognizer *)gesture {
// Do some other action as intended.
}
Of course this works only on iOS 3.2 and later.
You can also use this delegate method of UIGestureRecognizer.
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch;

How do you stop UITapGestureRecognizer from catching EVERY tap?

Hello I have an opengl view and on that I have a tab bar. I'm using a tap recognizer to tap different 3d objects on screen. In the tab bar I have a button but it doesn't work because the tap recognizer catches these taps too. How do I stop this? I've already tried this:
- (BOOL) gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
if ([touch.view isKindOfClass:[UIBarButtonItem class]]) return FALSE;
return TRUE;
}
I think I am somehow comparing wrong classess because when I debug it returns TRUE always.
Or you can just do [singleTap setCancelsTouchesInView:NO]. Example:
UITapGestureRecognizer *singleTap = [
[UITapGestureRecognizer alloc]
initWithTarget: self
action: #selector(yourSelector:)
];
[singleTap setCancelsTouchesInView:NO];
[[self view] addGestureRecognizer: singleTap];
if ([touch.view.superview isKindOfClass:[UIToolbar class]]) return FALSE;
This is how I got it to work. The superview is a UIToolbar, probably UIBarButtonIttem is a view after all.