I have two horizontal UIScrollview
s. I want to synchronise their scrolling when user drag fingers in 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 scroll views do scroll synchronously, however, the problem is all the bouncing and deceleration are gone. The whole scrolling movement becomes really rigid. If I remove all the syncing code, then each scroll view works just fine individually.
So, what is the problem? Or can UIScrollView
not be synchronised?
You can use topScrollView.panGestureRecognizer
and bottomScrollView.panGestureRecognizer
to take both gesture recognizers and add them to a common superview enclosing both scroll views. Pan gestures on this superview would then be recognized by both children.
You'll most likely also need to be the delegate of both recognizers and let them be recognized simulaneously:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
return YES;
}
I worked out the 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 too 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
Secondly, in your mainview,
- (void)viewDidLoad {
[super viewDidLoad];
[self.view addGestureRecognizer:self.scrollViewLeft.panGestureRecognizer];
[self.view addGestureRecognizer:self.scrollViewRight.panGestureRecognizer];
}
That's everything I need to set up two synchronized scrollviews. The real effect is much better than the regular way of sending/subscribing notifications in scrollview's scrollViewDidScroll and synchronize the contentOffset.
@jszumski answer in Swift
- Create a custom subclass of UIScrollView
- Conform to
UIGestureRecognizer
delegate - Override the
gestureRecognizer(_:shouldRecognizeSimultaneouslyWith:)
GestureRecognizerDelegate
method
public func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
return true
}
- Both collection views need to have the same superview. Add both gesture recognizers to your superview
yourSuperview.addGestureRecognizer(scrollView1.panGestureRecognizer)
yourSuperview.addGestureRecognizer(scrollView1)
Hope this helps!
来源:https://stackoverflow.com/questions/30398339/ios-how-sync-two-uiscrollview