I am working on an iphone (iOS 4.0 or later) app and having some troubles with touch handling between multiple views. I am having a view structure like this
I did something similar some time ago. I wanted to do two different things with one finger and two or more fingers. My solution might need some tweak for you and i can't ensure everything will work exactly the same in your code-environment. I did not find proper documentation of hitTest and why it is called multiple times in a row. So i did some testing and came to a solution, how to separate one and multi-finger gestures, which worked very well for my needs.
I had this view hierarchy:
---> A superView
|
---> ScrollView - A - all touches
|
---> ScrollView - B - only two+ finger scroll (exactly on top of A, completely blocking A).
I implemented the switch in hitTest of the superView:
BOOL endDrag; // indicates scrollviewB did finish
BOOL shouldClearHitTest; // bool to help calling the method clearHitTest only once.
BOOL multiTouch; // needed for the method clearHitTest to know if a multi-touch is detected or not
NSMutableArray *events; // store all events within one eventloop/touch;
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
if (!endDrag) {
if (!shouldClearHitTest) { // as hitTest will be called multible times in one event-loop and i need all events, i will clean the temporaries when everything is done
shouldClearHitTest = YES;
[[NSRunLoop mainRunLoop] performSelector:@selector(clearHitTest) target:self argument:nil order:1 modes:[NSArray arrayWithObject:NSRunLoopCommonModes]];
}
[events addObject:event]; // store the events so i can access them after all hittests for one touch are evaluated
if (event.type == UIEventTypeTouches && ([_events count] > 3 || [[event allTouches] count] > 0 || _currentEvent)) { // two or more fingers detected. at least for my view hierarchy
multiTouch = YES;
return scrollViewB;
}
}else {
endDrag = NO;
}
return scrollViewA;
}
- (void)clearHitTest {
if (shouldClearHitTest) {
shouldClearHitTest = NO;
[events removeAllObjects];
if (multiTouch) {
// Do some special stuff for multiTouch
}
multiTouch = NO;
}
}