IOS: how to sync two UIScrollviews
I have two horizontal UIScrollview
s. I want to sync their scrolling when the user drags their fingers on either of them. Here is my code:
self.topScrollView = [[UIScrollView alloc] initWithFrame:CGRectZero];
self.topScrollView.delegate = self;
self.topScrollView.bounces = YES;
self.bottomScrollView = [[UIScrollView alloc] initWithFrame:CGRectZero];
self.bottomScrollView.delegate = self;
self.bottomScrollView.bounces = YES;
...
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
if (scrollView == self.topScrollView)
{
self.bottomScrollView.delegate = nil;
}
else
{
self.topScrollView.delegate = nil;
}
...
}
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
...
self.topScrollView.delegate = self;
self.bottomScrollView.delegate = self;
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
...
self.topScrollView.delegate = self;
self.bottomScrollView.delegate = self;
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
// Sync the two scroll views
if (scrollView == self.topScrollView)
{
[self.bottomScrollView setContentOffset:scrollView.contentOffset animated:NO];
}
else
{
[self.topScrollView setContentOffset:scrollView.contentOffset animated:NO];
}
...
}
The two scrolls are scrolling in sync, however the problem is that all the bounces and slowdowns are gone. The whole scroll movement gets really stiff. If I remove all sync code then each scroll view only works individually. So what's the problem? Or is it impossible UIScrollview
not to sync?
source to share
You can use topScrollView.panGestureRecognizer
and bottomScrollView.panGestureRecognizer
to take both gesture recognizers and add them to a shared supervisor that includes both scrolling. Gestures on this supervision will be recognized by both children.
You should most likely also be a delegate to both resolvers and let them be recognized at the same time:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
return YES;
}
source to share
I have worked out a solution according to jszumski's answer. However, my situation is two vertical UIScrollViews side by side (scrollViewLeft and scrollViewRight). It should work for horizontal UIScrollViews without much modification.
First, create a custom UIScrollView.
//.h file
@interface CSScrollView : UIScrollView
@end
//.m file
@implementation CSScrollView
-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer{
return YES;
}
@end
Second, in your mainview,
- (void)viewDidLoad {
[super viewDidLoad];
[self.view addGestureRecognizer:self.scrollViewLeft.panGestureRecognizer];
[self.view addGestureRecognizer:self.scrollViewRight.panGestureRecognizer];
}
That's all I need to set up two synchronized scrolls. The real effect is much better than the usual way of sending / subscribing notifications in scrollview scrollViewDidScroll and keeping content in sync.
source to share