Reputation: 1721
What I'm trying to achieve is to create a functionality that when user clicks on an image, it pushes to next VC in navController.
in ViewDidLoad:
UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(singleTapAction:)];
[singleTap setNumberOfTapsRequired:1];
[singleTap setNumberOfTouchesRequired:1];
[self.scroll addGestureRecognizer:singleTap];
in singleTapAction:
- (void)singleTapAction:(UIGestureRecognizer *)singleTap {
UIView *view = singleTap.view;
if([view isKindOfClass:[UIImageView class]]){
NSLog(@"tapped on image");
}
else{
NSLog(@"Just tapped");
}
}
The if-logic doesn't seem to be working. It always gives "Just tapped" in the log. Even when I click on UIImageView, it detects that I've clicked on scrollview, which is container of ImageView here.
(lldb) po view;
$0 = 0x1f5ed6e0 <UIScrollView: 0x1f5ed6e0; frame = (0 0; 320 416); clipsToBounds = YES; autoresize = W+H; gestureRecognizers = <NSArray: 0x1f5edc20>; layer = <CALayer: 0x1f5ecb80>; contentOffset: {0, 0}>
EDIT:
The way I am populating the scrollview with imageviews is:
ALAssetsLibrary *assetsLibrary = [[ALAssetsLibrary alloc] init];
[assetsLibrary enumerateGroupsWithTypes:ALAssetsGroupSavedPhotos
usingBlock:^(ALAssetsGroup *group, BOOL *stop) {
if (nil != group) {
// be sure to filter the group so you only get photos
[group setAssetsFilter:[ALAssetsFilter allPhotos]];
NSLog(@"%d images found", group.numberOfAssets);
// for(int i = group.numberOfAssets - 5; i<group.numberOfAssets - 1; i++){
dispatch_apply(4, dispatch_get_global_queue(0, 0), ^(size_t i){
[group enumerateAssetsAtIndexes:[NSIndexSet indexSetWithIndex:i]
options:0
usingBlock:^(ALAsset *result, NSUInteger index, BOOL *stop) {
if (nil != result) {
ALAssetRepresentation *repr = [result defaultRepresentation];
// this is the most recent saved photo
UIImage *img = [self fixrotation:[UIImage imageWithCGImage:[repr fullResolutionImage]]];
UIImageOrientation orient = img.imageOrientation;
NSLog(@"orientation: %d", orient);
CGFloat aspectRatio = img.size.width/img.size.height;
UIImageView *imgView = [[UIImageView alloc] init];
imgView.frame = CGRectMake(10, self.yCord, 300, 300 /aspectRatio);
self.yCord += margin + (300/aspectRatio);
imgView.image = img;
imgView.layer.shadowRadius = 5.0;
imgView.layer.shadowColor = [UIColor blackColor].CGColor;
imgView.layer.cornerRadius = 4.0;
[imgView setUserInteractionEnabled:YES];
[self.scroll addSubview:imgView];
NSLog(@"%@", imgView);
NSLog(@"%f, %f, %f, %f", imgView.frame.origin.x, imgView.frame.origin.y, imgView.frame.size.width, imgView.frame.size.height);
*stop = YES;
self.scrollViewHeight = self.yCord + imgView.frame.size.height + margin;
CGSize scrollViewSize = CGSizeMake(320, self.scrollViewHeight);
[self.scroll setContentSize:scrollViewSize];
//self.scroll.frame = CGRectMake(0,0, 320, self.scrollViewHeight);
}
}];
});
}
*stop = NO;
} failureBlock:^(NSError *error) {
NSLog(@"error: %@", error);
}];
Another question which comes up now is, does setUserInteraction
works within block?
Upvotes: 1
Views: 1725
Reputation: 77631
You can detect if the touch was inside the image view like this...
- (void)singleTapAction:(UIGestureRecognizer *)singleTap {
CGPoint touchPoint = [singleTap locationInView:self.scroll];
if(CGRectContainsPoint(self.tappableImageView.frame, touchPoint){
NSLog(@"tapped on image");
}
else{
NSLog(@"Just tapped");
}
}
of if you have multiple image views then do something like this...
- (void)singleTapAction:(UIGestureRecognizer *)singleTap {
CGPoint touchPoint = [singleTap locationInView:self.scroll];
UIImageView *theTappedView;
for (UIView *subView in [self.scroll subViews]) {
if(CGRectContainsPoint(self.tappableImageView.frame, touchPoint)
&& [subView isKindOfClass:[UIImageView class]]) {
theTappedView = subView;
break;
}
}
if(theTappedView != nil){
NSLog(@"tapped on image");
}
else{
NSLog(@"Just tapped");
}
}
Note
This assumes that all the image views that will be tapped are subViews of the self.scroll
scrollView.
Upvotes: 2
Reputation:
why don't you adding tap gesture on ImageView rather than
adding on scroll...
and make code
[self.imageView setUserInteractionEnabled:YES];
Upvotes: 4
Reputation: 11607
Why don't you use a UIButton instead?
You can set a custom image for your button.
That way, the button handles the tapping event for you rather than you writing your own tap gesture handler.
I notice in your code, you have:
UIView *view = gesture.view;
Have you tried to changing it to:
UIImageView *view = gesture.view;
By the way, when you add your image to your scrollview, you probably want to add your tap gesture recognizer to that image immediately rather than add it to your scrollview.
Upvotes: -1
Reputation: 119031
In your code singleTap.view
is always the view that the tap gesture is attached to, not the view that you think was tapped.
You should create and attach a tap gesture for each image view individually rather than adding one to the container view.
Upvotes: 1