UIScrollView inside UIScrollView
UPDATE
This solution works always:
@implementation InnerScrollViewController <UIScrollViewDelegate, UIGestureRecognizerDelegate>- (void)viewDidLoad{ UISwipeGestureRecognizer* swipeGesture = [[[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleSwipe:)] autorelease]; swipeGesture.delegate = self; [self.view addGestureRecognizer:swipeGesture];}- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch{ _outerScrollView.scrollEnabled = NO; return YES;}- (void)handleSwipe:(UIGestureRecognizer*)gestureRecognizer{}- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView{ _outerScrollView.scrollEnabled = NO;}- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate{ if (!decelerate) { _outerScrollView.scrollEnabled = YES; }}- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{ _outerScrollView.scrollEnabled = YES;}@end
-----------------------------------------------------------------------
OLD ANSWER: doesn't work always
Here is how I solved the problem:
@implementation InnerView- (id)initWithFrame:(CGRect)frame{ self = [super initWithFrame:frame]; if (self) { self.delaysContentTouches = NO; } return self;}- (BOOL)touchesShouldBegin:(NSSet *)touches withEvent:(UIEvent *)event inContentView:(UIView *)view{ return NO;}
As I understand, self.delaysContentTouches = NO;
makes all events to be delivered immediately, and - (BOOL)touchesShouldBegin:(NSSet *)touches withEvent:(UIEvent *)event inContentView:(UIView *)view
prevents passing of these events by responder chain.
Modify your methods by below way:
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView{ if(scrollView == innerView) outerView.scrollEnabled = NO; else outerView.scrollEnabled = YES;}- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{ if(scrollView == innerView) { if(innerView.contentOffset.x + innerView.frame.size.width == innerView.contentSize.width) { outerView.scrollEnabled = NO; } else { outerView.scrollEnabled = YES; } }}
I have a similar issue. I found the solution, but it works only with innerScrollView.bounces = NO
.
@interface PageCtrl () @property (weak, nonatomic) IBOutlet UIScrollView *innerScrollView; @property(nonatomic) UIPanGestureRecognizer *panLockScroll;@end@implementation PageCtrl- (void)viewDidLoad { // ... self.innerScrollView.delegate = self; self.innerScrollView.bounces = NO; // disable bounces! self.panLockScroll = [[UIPanGestureRecognizer alloc]initWithTarget:self action:nil]; self.panLockScroll.delegate = self; [self.innerScrollView addGestureRecognizer:self.panLockScroll];}- (BOOL)gestureRecognizer:(UIGestureRecognizer*)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer*)otherGestureRecognizer{ if( gestureRecognizer == self.panLockScroll && otherGestureRecognizer == self.innerScrollView.panGestureRecognizer ){ return YES; } return NO;}@end