Detect tap on UIImageView inside UIScrollView - ios

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:)];

Related

UIPinchGestureRecognizer questions with subviews

I have the following code:
m_singleView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, nWidth - 1, nHeight - 1)];
m_singleView.backgroundColor = [UIColor clearColor];
UIPinchGestureRecognizer *pinchGesture = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:#selector(pinch:)];
[pinchGesture setCancelsTouchesInView:YES];
[m_singleView addGestureRecognizer:pinchGesture];
[m_singleView setUserInteractionEnabled:YES];
[m_MainView addSubview:m_singleView];
The issue that I'm having is that the pinch event for some reason does not fire. However, if i change line from [m_singleView addGestureRecognizer:pinchGesture] to [m_MainView addGestureRecognizer:pinchGesture]; then everything will work fine... can I not add the event for subview only?
Thanks!
Yes,you can add gesture to subview. i tested your code like below works fine.
First add delegate.
#interface ViewController : UIViewController<UIGestureRecognizerDelegate>
- (void)viewDidLoad {
[super viewDidLoad];
UIView *m_singleView = [[UIView alloc] initWithFrame:CGRectMake(50, 50, self.view.frame.size.width - 50, self.view.frame.size.height - 50)];
self.view.backgroundColor=[UIColor greenColor];
m_singleView.backgroundColor = [UIColor redColor];
UIPinchGestureRecognizer *pinchGesture = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:#selector(pinch)];
pinchGesture.delegate=self;
[pinchGesture setCancelsTouchesInView:YES];
[m_singleView addGestureRecognizer:pinchGesture];
[m_singleView setUserInteractionEnabled:YES];
[self.view addSubview:m_singleView];
}
-(void)pinch{
NSLog(#"In PInch");
}
you have used pinchgesture so you can use it like below.
Use Debug view hierarchy to see whether the size of m_singleView are 0 or not? If so, the size of m_singleView needs to be changed until you can touch it.

iOS UITapGestureRecognizer not working sometimes

Sometimes the selector method "tagClickAtIndex" not getting called.
UILabel* label = [[UILabel alloc] init];
label.userInteractionEnabled = YES;
UITapGestureRecognizer* tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tagClickAtIndex:)];
[label addGestureRecognizer:tapGesture];
-(void)tagClickAtIndex:(UITapGestureRecognizer*)gesture
{
NSMutableDictionary *mutDict = [[[NSMutableDictionary alloc]initWithDictionary:[_tagArray objectAtIndex:gesture.view.tag]] mutableCopy];
[mutDict setValue:[NSNumber numberWithLong:gesture.view.tag] forKey:#"index"];
[self.delegate tagClickAtIndex:mutDict];
}
you forget to set the frame of label, the reason it only define the clickable area
label.frame = CGRectMake(0,0,200,30)
[yourMainview addSubView:label]
and set if you need
tapGesture.numberOfTapsRequired = 1;
If you are programmatically creating UIlabel,your above code is not working.I tried your code.
UILabel* label = [[UILabel alloc] init];
label.userInteractionEnabled = YES;
UITapGestureRecognizer* tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tagClickAtIndex:)];
[label addGestureRecognizer:tapGesture];
It does not show anything.As you have not set the frame and add label view,it does not show.
So Then I tried creating UILabel freshly.I set frame,addSubView to self.view and I set the color as well as number of taps for label.
UILabel* label = [[UILabel alloc] init];
label.frame = CGRectMake(30, 100, 200, 100);
label.text = #"click me";
label.textColor = [UIColor blueColor];
[self.view addSubview:label];
Now Tap gesture recognizer for label
UITapGestureRecognizer* tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tagClickAtIndex:)];
tapGesture.numberOfTapsRequired = 1;
label.userInteractionEnabled = YES;
[label addGestureRecognizer:tapGesture];
in delegate method I put log,It calls everytime whenever I touch the label
-(void)tagClickAtIndex:(UITapGestureRecognizer*)gesture
{
NSLog(#"The tap is called");
.........
}
The printed statements shows
The tap is called

UIGestureRecognizer in objective-C++

I want to know the UIGestureRecognizer working or not in Objective-C++ because i've implemented this one but tap method never calling. So please let me know is it possible or not in Objective-C++.
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
UIImageView *imgView = [[UIImageView alloc] initWithFrame:CGRectMake(100, 100, 200, 200)];
imgView.image = [UIImage imageNamed:#"dharm"];
[self.view addSubview:imgView];
imgView.backgroundColor = [UIColor redColor];
UITapGestureRecognizer* tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tap:)];
tapRecognizer.numberOfTapsRequired = 1;
[tapRecognizer setDelegate:self];
[imgView addGestureRecognizer:tapRecognizer];
}
- (void)tap:(id)sender {
NSLog(#"Tap Pressed");
}
Try adding [imgView setUserInteractionEnabled:YES];

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);
}

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:)];

Resources