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
Related
I have a View which is the subView of the main view in iphone app I want that when subView is shown and user taps on part of the screen except the subView then subView should hide.
Here is the code which I got but it does not hide it :
UITapGestureRecognizer *tapGR;
tapGR = [[[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleTap:)] autorelease];
tapGR.numberOfTapsRequired = 1;
[self.View addGestureRecognizer:tapGR];
// Add a delegate method to handle the tap and do something with it.
-(void)handleTap:(UITapGestureRecognizer *)sender
{
if (sender.state == UIGestureRecognizerStateEnded) {
// handling code
[myViewSheet removeFromSuperView];
}
}
implement UIGestureRecognizerDelegate protocol:
.h:
#interface YourView : UIView<UIGestureRecognizerDelegate>
.m:
#implementation YourView{
UIView * subview;
}
...
subview = [[UIView alloc]initWithFrame:CGRectMake(0, 200, 320, 200)];
[self addSubview:subview];
UITapGestureRecognizer *tapGR;
tapGR = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleTap:)];
tapGR.numberOfTapsRequired = 1;
tapGR.delegate = self;
[self addGestureRecognizer:tapGR];
...
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
if (touch.view == subView)
{
return NO;
}
else
{
return YES;
}
}
You probably need to set userInteractionEnabled = YES on your main view (The one to which you are attaching the gesture recognizer.)
I've implemented 2 ImageViews with images and tapGestures, this works fine, now I want to segue to another ViewController dependent on which image I've tapped. I don't know how I have to declare my ImageView which ViewController it should call.
so my Code is:
-(void) initImageViews{
self.navigationItem.title = #"Menu";
UIImage *serviceImage = [UIImage imageNamed:#"Service.png"];
self.serviceImageView = [[UIImageView alloc] initWithImage:serviceImage];
[self.serviceImageView setFrame:CGRectMake(20, 20, 48,48 )];
[self.view addSubview:self.serviceImageView];
[self.view setBackgroundColor:[UIColor blackColor]];
UIImage *industryImage = [UIImage imageNamed:#"Industry.png"];
self.industryImageView = [[UIImageView alloc] initWithImage:industryImage];
[self.industryImageView setFrame:CGRectMake(73,20,48,48)];
[self.view addSubview:industryImageView];
UITapGestureRecognizer *singleTap =
[[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleSingleTap:)];
[self.industryImageView setUserInteractionEnabled:TRUE];
[self.serviceImageView setUserInteractionEnabled:TRUE];
[self.serviceImageView addGestureRecognizer:singleTap];
[self.industryImageView addGestureRecognizer:singleTap];
}
- (void)handleSingleTap:(UITapGestureRecognizer *)gestureRecognizer {
NSLog(#"Tapped!");
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"Service"]) {
SelectOptionViewController *controller = (SelectOptionViewController*)segue.destinationViewController;
}if ([segue.identifier isEqualToString:#"Industry"]) {
SelectOptionViewController *controller = (SelectOptionViewController*)segue.destinationViewController;
}
}
}
Thanks in advance :)
[self performSegueWithIdentifier:IdentifierForTheSegueiFromStoryBoard sender:nil];
EDIT: the seque must exist in the storyboard and must have an identifier.
If you don't want/need to use segues you could use:
if (i want controller A) {
[self presentViewController:ControllerA animated:YES completion:nil];
} else if (i want controller B)
[self presentViewController:ControllerB animated:YES completion:nil];
}
Create a seague in the storyboard with the identifier.then programatically call a segue like this
[self performSegueWithIdentifier: #"myidentifier" sender: self];
On parentClass(inheriting from UIView) i have:
[self addGestureRecognizer:_tapGesture]; // _tapGesture is UITapGestureRecognizer, with delegate on parentClass
On someClass:
[_myImageView addGestureRecognizer:_imageViewGestureRecognizer]; // _imageViewGestureRecognizer is UITapGestureRecognizer, with delegate on someClass
The problem is that when i tap on myImageView both gesture recognizers are firing. I want only _imageViewGestureRecognizer to work.
I've tried:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)recognizer shouldReceiveTouch:(UITouch *)touch {
UIView *gestureView = recognizer.view;
CGPoint point = [touch locationInView:gestureView];
UIView *touchedView = [gestureView hitTest:point withEvent:nil];
if ([touchedView isEqual:_imageViewGestureRecognizer]) {
return NO;
}
return YES;
}
But it ofc doesn't take upon consideration gesture recognizer from super class.
I did this little test and it worked perfectly...
#implementation View
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
self.backgroundColor = [UIColor whiteColor];
UITapGestureRecognizer* tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tapped1)];
[self addGestureRecognizer:tap];
UIImageView* img = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"test.png"]];
img.userInteractionEnabled = YES;
img.frame = CGRectMake(0, 0, 100, 100);
[self addSubview:img];
UITapGestureRecognizer* tap2 = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tapped2)];
[img addGestureRecognizer:tap2];
return self;
}
-(void)tapped1 {
NSLog(#"Tapped 1");
}
-(void)tapped2 {
NSLog(#"Tapped 2");
}
#end
What you wanted was iOS's default behaviour. Once a subview has taken care of a touch, its superview won't receive the touch anymore. Did you set userInteractionEnabled on the imageView?
I have implemented UITapGestureRecognizer on UIImageView, It is working on first tap. On First Tap, I am hiding that image and starting animation. Once the animations are completed, i am showing the image again. But After setting setHidden:FALSE, I am not getting the Tap event of that UIImageView.
Following is the code I am using :
- (void)viewDidLoad{
[super viewDidLoad];
defaultDogView= [[UIImageView alloc] initWithFrame:CGRectMake(3, 270, 110, 210)];
[defaultDogView setImage:[UIImage imageNamed:#"dog1.png"]];
defaultDogView.userInteractionEnabled = YES;
[self addGestureRecognizersToPiece:defaultDogView];
[self.view addSubview:defaultDogView];
}
- (void)addGestureRecognizersToPiece:(UIImageView *)piece
{
NSLog(#"in Gesture");
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(singleTapPiece:)];
[tapGesture setDelegate:self];
[piece addGestureRecognizer:tapGesture];
[tapGesture release];
UILongPressGestureRecognizer *longPressGesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(longPressPiece:)];
[piece addGestureRecognizer:longPressGesture];
[longPressGesture release];
NSLog(#"%#", [piece gestureRecognizers]);
}
- (void)singleTapPiece:(UITapGestureRecognizer *)gestureRecognizer
{
NSLog(#"Image Tapped");
/** Hide the default Image and start the animation ***/
[defaultDogView setHidden:TRUE];
/***Animating the Dog***/
[dogArray addObject:[SpriteHelpers setupAnimatedDog:self.view numFrames:69 withFilePrefix:#"dog" withDuration:(12) ofType:#"png" withValue:0]];
dogView = [dogArray objectAtIndex:0];
//[self addGestureRecognizersToPiece:dogView];
[self performSelector:#selector(callBubbleUpdater) withObject:nil afterDelay:5.5];
}
-(void)showDogFrame{
NSLog(#"%#",[defaultDogView gestureRecognizers]);
[defaultDogView setHidden:FALSE];
defaultDogView.userInteractionEnabled = YES;
}
When view is hidden or its alpha component is zero that view won't receive any UIGestureRecognizers.
I can suggest to use next approach if you need to hide some view (let's name it touchableView) but want it to respond to gestures:
Create backgroundView with the same frame as touchableView:
UIView *backgroundView = [[UIView alloc] initWithFrame:touchableView.frame];
Set background color of backgroundView to clearColor:
backgroundView.backgroundColor = [UIColor clearColor];
Reset position of touchableView:
CGRect frame = touchableView.frame;
frame.origin.x = 0;
frame.origin.y = 0;
Disable user interaction of touchableView:
touchableView.userInteractionEnabled = NO;
Add touchableView as subview to backgroundView:
[backgroundView addSubview:touchableView];
Add appropriate gesture recognizers to backgroundView.
Add backgroundView to view that you want.
Now you can hide touchableView but you will still receive gesture recognizers.
I don't test this but I think it should work.
sure
when UIImageView is hidden. it does not receive any touch events
set alpha zero for uiimageview
I am trying to attach a UITapGestureRecognizer to a webview that i am creating and then remove that view when a user taps the webview. Below is my sample code. What am i doing wrong? Thanks!
- (void) setupPuzzle1
{
puzzleDuration--;
//Create object circle
UIImageView *circleView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"red-circle.png"] highlightedImage:[UIImage imageNamed:#"red-circle.png"]];
UITapGestureRecognizer *recognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(removeImage:)];
recognizer.numberOfTapsRequired = 1;
recognizer.numberOfTouchesRequired = 1;
recognizer.delegate = self;
[circleView addGestureRecognizer:recognizer];
[recognizer release];
int x = rand()%280;
int y = rand()%420;
circleView.frame = CGRectMake(x,y,40,40);
[self.view addSubview:circleView];
if (puzzleDuration > 0)
{
[NSTimer scheduledTimerWithTimeInterval:1 target:self selector:#selector(setupPuzzle1) userInfo:nil repeats:NO];
}
}
#pragma mark - UITapGestureRecognizer methods
- (void)removeImage:(UITapGestureRecognizer *)recognizer
{
NSLog(#"Remove Image");
[[recognizer view] removeFromSuperview];
}
#end
I think you weren't talking about UIWebView at all. If you did, your code didn't reflect that. As such you are dealing with UIImageView and the reason is pretty straightforward as any UIImageView object by default has its userInteractionEnabled set to NO. You should change it to YES. So add this line,
circleView.userInteractionEnabled = YES;
and you aren't releasing it either. So add
[circleView release];
after you add it as a subview.