I've made a custom gesture recognizer and im adding it to my customView .
The custom gesture is a subclass of UIPanGestureRecognizer .
The other gesture that im adding is LongPressGestureRecognizer
CustomGestureRecognizer *pan;
pan = [[CustomGestureRecognizer alloc] initWithTarget:[self viewController] action:#selector(dragImage:)];
[pan setDirection:DirectionPangestureRecognizerVertical];
[pan setMinimumNumberOfTouches:1];
[pan setMaximumNumberOfTouches:1];
[custom addSubview:custom.imageView];
[custom addGestureRecognizer:pan];
[pan release];
UILongPressGestureRecognizer *highLight = [[UILongPressGestureRecognizer alloc] initWithTarget:[self viewController]
action:#selector(highlightImage:)];
[highLight setDelaysTouchesBegan:0.1];
[tempView addGestureRecognizer:highLight];
[highLight release];
Also i have implemented
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
if (![gestureRecognizer isKindOfClass:[UITapGestureRecognizer class]] && ![otherGestureRecognizer isKindOfClass:[UITapGestureRecognizer class]])
{
return YES;
}
return YES;
}
Both im my [self viewController] and in the self class but im still not getting both the gesture to work simultaniiosly .
You forgot to set the delegates of your gesture recognizers...that method will never be called.
Related
I am adding a UIImageView as a subview to a UIScrollView then i set the image.
Im trying to to use UITapGestureRecognizer.
The selector of the UITapGestureRecognizer is never called in iOS 5 (in iOS 6 it DOES!).
Tried many variations. this is my code:
UIImageView *imgView = [[UIImageView alloc]initWithFrame:CGRectMake(index*(IMAGE_WIDTH+10), 10.0, IMAGE_WIDTH, IMAGE_HEIGHT)];
[imgView setImageWithURL:[NSURL URLWithString:meal.RecommendedImageURL] placeholderImage:[UIImage imageNamed:#""]];
imgView.layer.cornerRadius = 4;
[imgView.layer setMasksToBounds:YES];
[imgView setUserInteractionEnabled:YES];
[imgView setMultipleTouchEnabled:YES];
[scrollView addSubview:imgView];
if (IOS_NEWER_OR_EQUAL_TO_5)
{
UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(imageTapped:)];
[imgView addGestureRecognizer:tapGestureRecognizer];
tapGestureRecognizer.numberOfTapsRequired = 1;
tapGestureRecognizer.enabled = YES;
tapGestureRecognizer.delegate = self;
[tapGestureRecognizer setCancelsTouchesInView:NO];
}
this is my selector which is only called in iOS5:
- (void) imageTapped: (UITapGestureRecognizer *)recognizer
{
//Code to handle the gesture
UIImageView *tappedImageView = (UIImageView*)recognizer.view;
GGFullscreenImageViewController *vc = [[GGFullscreenImageViewController alloc] init];
vc.liftedImageView = tappedImageView;
vc.liftedImageView.contentMode = UIViewContentModeScaleAspectFit;
if (IOS_NEWER_OR_EQUAL_TO_5) {
[self.parentViewController presentViewController:vc animated:YES completion:nil];
}
else
{
[self.parentViewController presentModalViewController:vc animated:YES];
}
}
In addition to that, i tried to setCancelsTouchesInView to YES in my UIScrollView but it doesn't work either.
Thanks for your help!
try to add Gesture in Scrollview then check iskind of class image view
UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(imageTapped:)];
[scrollview addGestureRecognizer:tapGestureRecognizer];
tapGestureRecognizer.numberOfTapsRequired = 1;
tapGestureRecognizer.enabled = YES;
tapGestureRecognizer.delegate = self;
[tapGestureRecognizer setCancelsTouchesInView:NO];
- (BOOL)gestureRecognizer:(UITapGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
// test if our control subview is on-screen
if ([touch.view isKindOfClass:[UIImageView class]]) {
// we touched a button, slider, or other UIControl
return YES;
}return NO;
}
Implement the 3 methods of UIGestureRecognizerDelegate & return default values:
-(BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer;
-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer;
-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch;
Ok i solved it very EASILY!
the problem was setting the delegate of the UITapGestureRecognizer to self.
when i removed the delegate = self, it started working :)
Thanks for your assistance
In my app I need have a swipe gesture recogniser on my background scroller for the up direction. Here is my code below
It is in viewDidLoad
UISwipeGestureRecognizer *Swipe = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(SwipeRecognizer:)];
Swipe.direction = UISwipeGestureRecognizerDirectionUp;
[backgroundScroller addGestureRecognizer:Swipe];
and it is the SwipeRecognizer:
- (void) SwipeRecognizer:(UISwipeGestureRecognizer *)sender {
if (sender.direction | UISwipeGestureRecognizerDirectionUp){
NSLog(#" *** SWIPE UP ***");
}
}
The problem is I cant enable scrolling and capture the gesture simultaneously. when I said scrolling is not enabled, I can recognise the gesture. But I need to to scrolling and gesture recognition simultaneously. isn't it possible?
Override the gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer: method to don't block the UIScrollViews Pan recognizer
And it will work…
Dont forget to add delegate to self for gesture recogniser. As mentioned in #death7eater's comment.
I solved my problem like that:
This is for the viewDidLoad:
UISwipeGestureRecognizer *Swipe = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(SwipeRecognizer:)];
Swipe.direction = UISwipeGestureRecognizerDirectionUp;
[backgroundScroller addGestureRecognizer:Swipe];
Swipe.delegate = self;
This is the SwipeRecognizer method:
- (void) SwipeRecognizer:(UISwipeGestureRecognizer *)sender {
if (sender.direction | UISwipeGestureRecognizerDirectionUp){
NSLog(#" *** SWIPE UP ***");
}
}
And thanks to #lukaswelte this allows to perform multiple gestures simultaneously:
- (BOOL) gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
return YES;
}
When my hitView comes partially from the superview after a UIPanGestureRecognizer, the UILongPressGestureRecognizer don't work. Why?
- (id)initWithFrame:(CGRect)frame
{
UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(pan:)];
[panGesture setMaximumNumberOfTouches:1];
[panGesture setDelegate:self];
[_glassesImage addGestureRecognizer:panGesture];
UILongPressGestureRecognizer *longPressGesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(enchance:)];
longPressGesture.minimumPressDuration = 0.2;
[_glassesImage addGestureRecognizer:longPressGesture];
[self addSubview:_glassesImage];
}
- (void)enchance:(UILongPressGestureRecognizer *)gestureRecognizer
{
UIView *hitView = [gestureRecognizer view];
hitView.alpha=0.6;
inLongPress=YES;
gestureRecognizer.allowableMovement = 200;
if ([gestureRecognizer state] == UIGestureRecognizerStateEnded){
hitView.alpha=1.0;
inLongPress=NO;
}
}
Try defining a delegate for your gesture recognizers and then provide an implementation for:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
(refs)
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer{
return YES;
}
Add delegate to longPressGesture.
longPressGesture.delegate = self;
I think it will be helpful to you.
In iOS, is it possible to put a tap recognizer on a UIWebView, so that when someone single-taps the web view, an action gets performed?
Code below doesn't seem fire handleTap when I tap my webView.
Thanks.
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self
action:#selector(handleTap)];
tap.numberOfTapsRequired = 1;
[webView addGestureRecognizer:tap];
[tap release];
-(void) handleTap {
NSLog(#"tap");
}
I found that I had to implement this method to get it to work:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
return YES;
}
Your UIViewController subclass should implement UIGestureRecognizerDelegate and return YES from gestureRecognizer: shouldReceiveTouch: when appropriate.
Then you can assign it to the delegate property of your UIGestureRecognizer.
tap.delegate = self;
Add UIGestureRecognizerDelegate to view controller
<UIGestureRecognizerDelegate>
Add Tap Gesture to Webview.
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(flip)];
tap.numberOfTapsRequired = 1;
tap.delegate = self;
[_webview addGestureRecognizer:tap];
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
return YES;
}
I have added two gesture recognizers to a view. One will handle the view drag and the other the double tap. Something like
UITapGestureRecognizer *doubleTap =
[[UITapGestureRecognizer alloc] initWithTarget:self
action:#selector(deleteThisView)];
[doubleTap setDelegate:self];
[doubleTap setCancelsTouchesInView:YES];
[doubleTap setNumberOfTapsRequired:1];
[base addGestureRecognizer:doubleTap];
[doubleTap release];
UIPanGestureRecognizer *panGesture = nil;
panGesture = [[UIPanGestureRecognizer alloc]
initWithTarget:self action:#selector(drag:)];
[panGesture setMaximumNumberOfTouches:1];
[panGesture setDelegate:self];
[base addGestureRecognizer:panGesture];
[panGesture release];
The problem is this: as the view can move, the double tap is somehow difficult to obtain, because the view can slide one hair to one side or the other and iOS will not recognize it as double tap, and instead will see it as two moves and the drag method will run twice.
I am not seeing how this can be done. Any clues?
thanks
There's a delegate method that will tell the central gesture code that two recognizers might be going at the same time:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer
shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
if (gestureRecognizer==_panRecognizer && otherGestureRecognizer==_swipeRecognizer)
return YES;
if (gestureRecognizer==_swipeRecognizer && otherGestureRecognizer==_panRecognizer)
return YES;
return NO;
}
Maybe you can try something like that.
Here is Vagrant's answer in swift:
func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWithGestureRecognizer otherGestureRecognizer: UIGestureRecognizer) -> Bool {
if gestureRecognizer == panRecognizer && otherGestureRecognizer == swipeRecognizer {
return true
}
if gestureRecognizer == swipeRecognizer && otherGestureRecognizer == panRecognizer {
return true
}
return false
}
Don't forget to implement the delegate protocol and set your gestures' delegates to self (I forgot this initially).