The way to do this is to subclass the subviews that are eating the touch events and not allowing the UIScrollView to get them. Then, override the pointInside:
method (with the appropriate exception for UI that you want to still work). For example:
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
{
// Confine the offending control to a certain area
CGRect frame = CGRectMake(0, 0,
self.frame.size.width,
self.frame.size.height - 100.00);
// Except for subview buttons (or some other UI element)
if([self depthFirstButtonTest:self pointInside:point withEvent:event])
{
return YES;
}
return (CGRectContainsPoint(frame, point));
}
- (BOOL)depthFirstButtonTest:(UIView*)view pointInside:(CGPoint)point withEvent:(UIEvent *)event
{
for (UIView * subview in view.subviews)
{
if([self depthFirstButtonTest:subview pointInside:point withEvent:event])
{
return YES;
}
}
// Is it a button? If so, perform normal testing on it
if ([view isKindOfClass:[UIButton class]]) {
CGPoint pointInButton = [view convertPoint:point fromView:self];
if ([view pointInside:pointInButton withEvent:event]) {
return YES;
}
}
return NO;
}