According to the Apple iOS Scroll View Programming Guide now..
To create a rich user experience, you may want to nest scroll views in your application. Before iOS 3.0 it was difficult, if not impossible to accomplish this. In iOS 3.0, this functionality is fully supported and works automatically.
So nesting scrollviews is perfectly fine > iOS 3. To answer your question, I added scrollview C as a subview to a "container" UIView - before adding that container view to scrollview B. Seems to stop the bounce pulling the parent scroll view down, although I did have to swipe pretty hard and fast to make it exhibit the behaviour you described without the container view.
@interface TiledScrollView : UIScrollView @end
@implementation TiledScrollView
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if(self)
{
self.layer.borderColor = [UIColor whiteColor].CGColor;
self.layer.borderWidth = 10.f;
}
return self;
}
- (void)setContentSize:(CGSize)contentSize
{
[super setContentSize:contentSize];
BOOL horizontal = contentSize.width > self.frame.size.width;
if(horizontal)
{
CGFloat col = self.contentSize.width / 10.f;
for (int i = 0; i < 10; i++)
{
UIView * view = [[UIView alloc] initWithFrame:CGRectMake(i * col, 0, col, self.contentSize.height)];
view.backgroundColor = [UIColor colorWithHue:(arc4random() % 100) / 100.f saturation:1.f brightness:1.f alpha:1.f];
[self addSubview:view];
}
}
else
{
CGFloat row = self.contentSize.height / 10.f;
for (int i = 0; i < 10; i++)
{
UIView * view = [[UIView alloc] initWithFrame:CGRectMake(0, i * row, self.contentSize.width, row)];
view.backgroundColor = [UIColor colorWithHue:(arc4random() % 100) / 100.f saturation:1.f brightness:1.f alpha:1.f];
[self addSubview:view];
}
}
}
@end
#import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
CGRect bounds = [UIScreen mainScreen].bounds;
TiledScrollView * A = [[TiledScrollView alloc] initWithFrame:CGRectMake(0, 0, bounds.size.width, bounds.size.height)];
TiledScrollView * B = [[TiledScrollView alloc] initWithFrame:CGRectMake(0, 0, bounds.size.width, bounds.size.height / 2.f)];
TiledScrollView * C = [[TiledScrollView alloc] initWithFrame:CGRectMake(0, 0, bounds.size.width, bounds.size.height / 4.f)];
[A setContentSize:CGSizeMake(bounds.size.width * 4, bounds.size.height)];
[B setContentSize:CGSizeMake(bounds.size.width, bounds.size.height * 4)];
[C setContentSize:CGSizeMake(bounds.size.width, bounds.size.height * 4)];
UIView * container = [[UIView alloc] initWithFrame:CGRectMake(0, 0, bounds.size.width, bounds.size.height / 4.f)];
[container addSubview:C];
[B addSubview:container];
[A addSubview:B];
[self.view addSubview:A];
}
@end