Fahim Parkar,
Not sure this is what you want or have I understood you wrong :) I believe you can makeuse of hitTest:
to solve it :)
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
UIView *hitView = [super hitTest:point withEvent:event];
if (hitView && CGRectContainsPoint(ScrollView001.frame, point)) {
return ScrollView001;
}
return hitView;
}
How it Works
Whenever you tap on screen scorllView002 covering whole screen captures the touch :) Hence hitTest of ScrollView002 gets called :) If by anyway you can access the ScrollView001 (that should be easy as they are in same ViewController) you can verify if the touch point is inside ScrollView001, If yes you can return the touchView as ScrollView001.
As a result ScrollView001 will get touch rather then ScrollView002 :)
EDIT
As you have mentioned you did try my method and it still din work for you :) I decided to give a shot myself and realized it works absolutely fine. Please have a look :)

I believe this is what your situation :) I have added two scrollViews on top of each other. Small scrollView (myScrollView) being below the bigger fullscreen scrollView (TestScrollView).
Now when I tap on the screen there is no way myScrollView getting touch :)
But thats what we need so here is what I did :)
I created a subclass of ScrollView called TestScrollView and set the same for the top scrollView :)
TestScrollView.swift
import UIKit
class TestScrollView: UIScrollView {
var scrollViewBehind : UIView!
/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
override func drawRect(rect: CGRect) {
// Drawing code
}
*/
override func hitTest(point: CGPoint, withEvent event: UIEvent?) -> UIView? {
let hitView = super.hitTest(point, withEvent: event)
if hitView != nil && CGRectContainsPoint(scrollViewBehind.frame,point) {
return scrollViewBehind
}
return hitView;
}
}
I have created a variable called scrollViewBehind to hold the reference of smallerScrollView which is behind it in storyboard (I am very much aware that holding a reference like this to view behind is not a great design :) But I believe it is good enough to explain the logic )
This is my ViewController code :)
import UIKit
class ViewController: UIViewController,UIGestureRecognizerDelegate {
@IBOutlet var myScrollView: UIScrollView!
@IBOutlet var testScrollView: TestScrollView!
override func viewDidLoad() {
super.viewDidLoad()
testScrollView.scrollViewBehind = myScrollView
let tap = UITapGestureRecognizer(target: self, action: Selector("handleTap"))
tap.delegate = self
myScrollView .addGestureRecognizer(tap)
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func handleTap(){
print("Me tapped")
}
}
EDIT
As per our discussion, I realized that you have a collectionView as a subView on smaller ScrollView which itself is behind the full screen scrollView :)
I have kept the answer above as it is in Swift and it also explains how to handle hitTest to handover the control to scrollView below from the scrollView above. Though it does not completely solve your question, might give a solution enough to somebody else :)
Now as per your question, when user taps, the scrollView above captures the touch and the touch should be forwarded to collectionView on top of smaller scrollView :)
So following the same approach explained above :) I created a subclass of ScrollView lets call TestScrollView (Answer is in objective C as per your requirement)
TestScrollView.h
#import <UIKit/UIKit.h>
@interface TestScrollView : UIScrollView
@property (nonatomic,strong) UICollectionView *collectionViewBehind;
@property (nonatomic,strong) UIScrollView *scrollViewBehind;
@end
TestScrollView.m
#import "TestScrollView.h"
@implementation TestScrollView
/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
// Drawing code
}
*/
-(UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
UIView *hitView = [super hitTest:point withEvent:event];
CGPoint myPoint = [self convertPoint:point toView:self.scrollViewBehind];
if (hitView != nil && CGRectContainsPoint(self.scrollViewBehind.frame,point)) {
return self.collectionViewBehind;
}
return hitView;
}
@end
If you notice properly TestScrollView has two properties namely collectionViewBehind and scrollViewBehind this is to hold the reference of below scrollView and collectionView :)
What hitTest does is already explained above. Though, all it does is it checks the touch point if touch point is inside scrollView it returns the collectionView. What taht does is it transfers the touch event to collectionView.
Now go to storyboard select the topScrollView and set its class as TestScrollView.
In ViewController which loads these scrollViews add,
#import "ViewController.h"
#import "TestScrollView.h"
@interface ViewController ()<UICollectionViewDelegate,UICollectionViewDataSource,UIGestureRecognizerDelegate>
@property (strong, nonatomic) IBOutlet TestScrollView *testScrollView;
@property (strong, nonatomic) IBOutlet UICollectionView *collectionView;
@property (strong, nonatomic) IBOutlet UIScrollView *scrollView;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.testScrollView.collectionViewBehind = self.collectionView;
self.testScrollView.scrollViewBehind = self.scrollView;
self.collectionView.delegate = self;
self.collectionView.dataSource = self;
[self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"test"];
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTap:)];
tapGesture.numberOfTapsRequired = 1;
tapGesture.delegate = self;
[self.collectionView addGestureRecognizer:tapGesture];
// Do any additional setup after loading the view, typically from a nib.
}
Yes, If you have noticed you noticed it right I am adding a TapGesture recognizer to UICollectionView. Though we managed to handover the touch to UICollectionView we noticed that didSelectItemAtIndexPath was never triggered. So this is a small work around.
Though adding GestureRecognizer to collectionView is not much advisable here in this case it is still ok as we are only overriding single tap leaving all other gestures unaltered.
So now whenever user taps the scrollView above gestureRecognizer of UICollectionView triggers and calls our selector :) Now all you have to do is to figure out which cell was tapped and select it programmatically :)
-(void)handleTap:(UIGestureRecognizer *)recognizer {
[self collectionView:self.collectionView didSelectItemAtIndexPath:[self.collectionView indexPathForItemAtPoint:[recognizer locationInView:self.collectionView]]];
}
Finally enjoy the control at
-(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{
NSLog(@"Hi indexPath tapped is %@",indexPath);
}
Finally here is a link to the project : https://github.com/sandeeplearner/UnderlayingClickableViews