TapGesture recognizer on multiple UIImageView not working - ios

TapGesture recognizer on multiple UIImageView is not working, while it detects last added imageviews gesture.. I have done this,
UITapGestureRecognizer *tapped = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(myFunction:)];
tapped.numberOfTapsRequired = 1;
tapped.delegate = self;
UIImageView *sample_book1= [[UIImageView alloc]initWithFrame:CGRectMake(70, 135, 100,125) ];
sample_book1.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"mathematics.png"]];
sample_book1.userInteractionEnabled = YES;
sample_book1.tag = 0;
[sample_book1 addGestureRecognizer:tapped];
[self.view addSubview:sample_book1];
UIImageView *sample_book2= [[UIImageView alloc]initWithFrame:CGRectMake(220, 135, 100,125) ];
sample_book2.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"biology.png"]];
sample_book2.userInteractionEnabled = YES;
sample_book2.tag = 1;
[sample_book2 addGestureRecognizer:tapped];
[self.view addSubview:sample_book2];
UIImageView *sample_book3= [[UIImageView alloc]initWithFrame:CGRectMake(370, 135, 100,125) ];
sample_book3.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"chemistry.png"]];
sample_book3.userInteractionEnabled = YES;
sample_book3.tag = 2;
[sample_book3 addGestureRecognizer:tapped];
[self.view addSubview:sample_book3];
The tap gesture is not working in sample_book1,sample_book2.... it's only working in sample_book3.. What i'm doing wrong..

As borrrden said, when trying to track gesture, each view must have its own gestureRecognizer.
For each of your sample_books, you should use
[sample_bookX addGestureRecognizer:[[UITapGestureRecognizer alloc]initWithTarget:self action:#selector(myFunction:)]];
instead of trying to add multiple times the same GR
The argument received by myFunction: would then be the proper tapGR and you could get to the tapped imageView by calling sender.view (providing your myFunction signature look like
- (void) myFunction:(UIGestureRecognizer *)sender
Cheers,

What you are doing wrong is trying to use the gesture in a way that it is not supposed to be used. A gesture can only be attached to one view. You need to make a new one for each view.

Related

How to handle event of code-created UIView

I have unknown amount of UIImageViews which are created in the code, not in the xib file and i need to handle the taps on those images. The handling of each of this image view is going to be the same. How do i do this?
Demo code for your implemantation
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
UIImageView *imgView1 = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tapDetected:)];
singleTap.numberOfTapsRequired = 1;
[imgView1 setUserInteractionEnabled:YES];
[imgView1 addGestureRecognizer:singleTap];
imgView1.tag = 1;
imgView1.backgroundColor = [UIColor redColor];
[self.view addSubview:imgView1];
UIImageView *imgView2 = [[UIImageView alloc] initWithFrame:CGRectMake(0, 200, 100, 100)];
UITapGestureRecognizer *singleTap2 = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tapDetected:)];
singleTap.numberOfTapsRequired = 1;
[imgView2 setUserInteractionEnabled:YES];
[imgView2 addGestureRecognizer:singleTap2];
imgView2.tag = 2;
imgView2.backgroundColor = [UIColor blueColor];
[self.view addSubview:imgView2];
}
-(void)tapDetected:(UITapGestureRecognizer *)gestureRecognizer{
UIImageView *myImg = (UIImageView*)gestureRecognizer.view;
NSLog(#"tag : %ld",(long)myImg.tag);
}
Try this code to add a gesture recogniser
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:#selector(action:)];
[_imgview addGestureRecognizer:tap];
_imgview.userInteractionEnabled = YES;
You can add UITapGestureRecognizer to detect touch on UIImageView.
Just use below method with argument, your image view and a unique tag, and you're done !
- (void) setTapGestureOnImageView:(UIImageView *)imageView withTag:(NSInteger)tag {
//this is important, by default user interaction isn't enabled, we have to enable it.
imageView.userInteractionEnabled = YES;
//create a tap gesture (in example this is sinlge tap) with target and action to call when user tap
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(detectTap:)];
//you can customize taps too
//tap.numberOfTapsRequired = 2;
//tap.numberOfTouchesRequired = 2;
//add gesture on image view
[imageView addGestureRecognizer:tap];
}
- (void)detectTap:(UIGestureRecognizer *)recognizer {
//Get the tapped image view from recognizer
UIImageView *imageView = (UIImageView *)recognizer.view;
//Check for condition, which image view tapped
if(imageView.tag == 1) {
//do something 1st imageview
}
else if(imageView.tag == 2) {
//do something for 2nd imageview
}
else {
//do something else
}
}
May be this will be useful to you
- (void)viewDidLoad
{
NSArray *imagesArray = [NSArray arrayWithObjects:#"statement_card_1.png", #"statement_card_2.png", #"statement_card_3.png", #"statement_card_4.png", #"statement_card_5.png", nil];
short xPadding = 10;
for (int i = 0; i< imagesArray.count; i++)
{
UIImage *imageRecipe =[UIImage imageNamed:[imagesArray objectAtIndex:i]];
UIImageView *imgView = [[UIImageView alloc]initWithFrame:CGRectMake(xPadding, xPadding+(i*60),imageRecipe.size.width, imageRecipe.size.height)];
imgView.tag =IMAGETAG + i;
[imgView setImage:imageRecipe];
imgView.userInteractionEnabled = YES;
UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tapDetected:)];
[imgView addGestureRecognizer:singleTap];
[self.view addSubview:imgView];
}
}
-(void)tapDetected:(UITapGestureRecognizer *)recognizer
{
UIImageView *TempImg = (UIImageView *)recognizer.view;
NSLog(#"tag : %ld",(long)TempImg.tag);
}

Visible text of UITextView in UIScrollView which has subview UIImageView

when typing in the UITextView the text is not visible;
when typing is done the text is not visible.
How to make it visible?
The code is below. I do not put the UITextView related code intentionally as only font and alignment properties are set.
// Setup the background image view.
[self.backgroundImageView setBackgroundColor:[UIColor blackColor]];
[self.view sendSubviewToBack:self.backgroundImageView];
// Set the image view.
CGRect r = CGRectMake(0, 0, self.TextView.bounds.size.width, 455);
ImageView = [[UIImageView alloc] initWithFrame:r];
// Set up the scroll view for the image zooming in/out and scrolling.
imgScrollView = [[UIScrollView alloc] initWithFrame:ImageView.bounds];
[imgScrollView setScrollEnabled:YES];
[imgScrollView setClipsToBounds:YES];
[imgScrollView addSubview:ImageView];
[imgScrollView setBackgroundColor:[UIColor clearColor]];
[imgScrollView setContentSize:ImageView.frame.size];
imgScrollView.maximumZoomScale = 5.0;
imgScrollView.delegate = self;
UITapGestureRecognizer *doubleTapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(scrollViewDoubleTapped:)];
doubleTapRecognizer.numberOfTapsRequired = 2;
doubleTapRecognizer.numberOfTouchesRequired = 1;
[imgScrollView addGestureRecognizer:doubleTapRecognizer];
[imgScrollView sendSubviewToBack:self.TextView];
[self.view addSubview:imgScrollView];
UPDATE
[imgScrollView addSubview:self.TextView];
the line of code above solved this.

UITapGestureRecognizer on UILabels in subview of UIScrollView not working

I have a problem where my UITapGestureRecognizer on my UILabels in a content view in my UIScrollView is not calling it's methods.
The view hierarchy is as follows:
scrollView (UIScrollView)
contentView (UIView)
testLabel (UILabel) - here is where the UITapGestureRecognizer is attached
I have distilled the code down to an example to highlight the problem
// Set scrollview size - Added in Storyboad
[scrollView setContentSize:CGSizeMake([arrayOfVerbs count]*self.view.frame.size.width, scrollView.contentSize.height)];
[scrollView setCanCancelContentTouches:YES]; // Tried both yes and no
[scrollView setPagingEnabled:YES];
// Add content view
UIView *contentView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, scrollView.contentSize.width, scrollView.contentSize.height)];
[scrollView addSubview:contentView];
// Add test UILabel
UILabel *testLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 200, 100)];
[testLabel setBackgroundColor:[UIColor redColor]];
[testLabel setText:#"Test touch"];
[testLabel setUserInteractionEnabled:YES];
[contentView addSubview:testLabel];
// Add gesture recogniser
UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(playSound:)];
singleTap.numberOfTapsRequired = 1;
[testLabel addGestureRecognizer:singleTap];
And this is the method that the tap gesture recogniser should call
- (void)playSound:(UITapGestureRecognizer *)sender {
NSLog(#"play sound");
if(sender.state == UIGestureRecognizerStateEnded)
{
int pronounNumber = [sender.view tag];
int exampleNumber = (int)sender.view.frame.origin.x%(int)self.view.frame.size.width;
NSLog(#"Pronoun is %i and example is %i", pronounNumber, exampleNumber);
}
}
This method is never called when I tried to touch on the UILabel.
I have tried setting the property canCancelContentTouches to both YES and NO on the scroll view as suggested by this thread, but it's still not working.
The strange thing is, if I add a UILabel outside of the scrollView, then the gesture recogniser works! So the problem only occurs in my contentView which is a subview of my scrollView.
I am using auto-layout, if that might be any difference?
Thanks!
The scroll view also has a gesture recogniser. By default, only 1 gesture recognizer can be handling touches at any one time. You need to make yourself the delegate of your gesture and then implement gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer: to return YES. This will allow it to work at the same time as the scroll view.
Add delegate to tagGestures,
UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(playSound:)];
singleTap.numberOfTapsRequired = 1;
singleTap.delegate = self;
[testLabel addGestureRecognizer:singleTap];
EDIT:-
contentView.userInteractionEnabled = YES;
put this line your code it'l work.
[yourlabel.addGestureRecognizer:tapGestureDeFromage];
should add the gesture explicitly to your labels.

UINavigationItem touchView touch size

I'm setting a view on my UINavigationItem's touchView and adding a tap gesture recognizer to it. What's weird, is that the tap recognizer is getting called even when the tap is outside of the view. Any idea why this might be happening?
UIView *testView = [[UIView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 120.0f, 20.0f)];
testView.backgroundColor = [UIColor redColor];
UIGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(doStuff:)];
tapRecognizer.cancelsTouchesInView = YES;
[testView addGestureRecognizer:tapRecognizer];
testView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
self.navigationItem.titleView = testView;
I can click outside the red box and still trigger the gesture recognizer.
use this way
UITapGestureRecognizer *tapRecognizer =
[[UITapGestureRecognizer alloc] initWithTarget:self
action:#selector(doStuff:)];
instead of this code
UIGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(doStuff:)];

Detect tap on UIImageView inside UIScrollView

I have a horizontal scrollview filled with UIImageViews.
I want to detect a tap on the UIImageView and have its background color changed.
Somehow the tap gesture is not working or so.
However, when I add a tap gesture to the scrollview, it works. The scrollview.background color can be changed.
But I want to detect a tap on the UIImageViews it contains!
UIScrollView* scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 50, 768, 127)];
[scrollView setScrollEnabled:YES];
scrollView.backgroundColor = [UIColor orangeColor];
[scrollView setShowsHorizontalScrollIndicator:NO];
UIImageView *contentOfScrollView = [[UIImageView alloc]initWithFrame:CGRectMake(0, 1, 1130, 125)];
scrollView.contentSize = CGSizeMake(contentOfScrollView.frame.size.width, contentOfScrollView.frame.size.height);
for (int aantal=0; aantal < 6; aantal++) {
UIImageView *item = [[UIImageView alloc] initWithFrame:CGRectMake(3+(aantal*188), 0, 185, 125)];
item.backgroundColor = [UIColor yellowColor];
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:item action:#selector(imageTapped:)];
tap.numberOfTapsRequired = 1;
tap.cancelsTouchesInView=YES;
item.userInteractionEnabled = YES;
[item addGestureRecognizer:tap];
[contentOfScrollView addSubview:item];
}
//UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(imageTapped:)];
//[scrollView addGestureRecognizer:tap];
scrollView.userInteractionEnabled=YES;
scrollView.delaysContentTouches=NO;
[scrollView addSubview:contentOfScrollView];
[self.view addSubview:scrollView];
And this is the imageTapped function.
-(void)imageTapped:(UITapGestureRecognizer *)gesture
{
NSLog(#"tapped!");
gesture.view.backgroundColor = [UIColor whiteColor];
}
User interaction is set to NO by default for UIImageView, so you need to set it to YES.
You set it to yes for "item", but not for contentOfScrollView.
Your error is here:
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:item action:#selector(imageTapped:)];
You need to change the target to "self" instead of "item", then it won't crash.
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(imageTapped:)];

Resources