How to disable scroll in a specific subview of a UIScrollView
Asked Answered
W

3

7

I have a UIScrollView which contains many subviews. One of the subview is designed to show a linechart, so the user may need to drag horizontally. The truth is when I mean to drag my finger horizontally, the vertical scroll of the UIScrollView is easily activated. Now I want to disable the vertical scroll in the subview of chart, and leave it active in the rest parts.

I've tried to add a UIPanGestureRecognizer to my chart subview. It did disabled the vertical scroll but the horizontal scroll is disabled too. I know I can write codes in the handler of the gesture recognizer to tell vertical or horizontal scroll i needed. But the horizontal scroll is actually managed by the subview's controller, which is a third-party library (JBChartView to be specific). I want to know whether there is a simple way to solve this problem.

Many thanks.

Weathersby answered 24/11, 2014 at 8:37 Comment(2)
If your are the two scrollView accesible by code. You can implement a delegate method for your inside scrollView and to make the y position doesn't change. (If you write your code), I could give to you more help.Ellingson
Does your scroll view contain another scroll view with the line chart?Trombidiasis
W
4

Thanks to Dev and Astoria, I have solved this problem. Now I want post my solution here in case there will be someone who meet the same problem as mine.

Here is the result:

Final Result

Because the Horizontal Only View is not a scrollView (actually it's a JBLineChartView), the easiest scrollViewDidScroll way doesn't help.

We still need GestureRecognizer to achieve this goal, but in a more basic way, just as Dev said, -touchesBegan methods. Sadly UIScrollView will not respond to this kind of touch, we need write a category for it, as code below:

@implementation UIScrollView (UITouchEvent)
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    [[self nextResponder] touchesBegan:touches withEvent:event];
    [super touchesBegan:touches withEvent:event];
    self.scrollEnabled = YES;//This is the only line that you need to customize
}
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
    [[self nextResponder] touchesMoved:touches withEvent:event];
    [super touchesMoved:touches withEvent:event];
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
    [[self nextResponder] touchesEnded:touches withEvent:event];
    [super touchesEnded:touches withEvent:event];
}
@end

Ha, then it works!

BTW....This is my first question on StackOverflow, and it's a really nice tour.

Weathersby answered 25/11, 2014 at 9:53 Comment(1)
how do you call [[self nextResponder] touchesMoved:touches withEvent:event]; from the uiviewcontroller?Patrilineage
I
3

Use -touchesBegan of UIResponder class. If the touch is from your subview(which you don't want to scroll). Disable scrolling of the scrollview. if -touchesEnded or -touchesCancelled is called for that view. enable scrolling of your scrollview.

Inform answered 24/11, 2014 at 9:32 Comment(2)
This does work. However UIScrollView does not respond to touchedBegan. I have to write a category to extend it. Did miss something so it looks a little inconvenient?Weathersby
UIScrollView does not respond to -touchesBegan, But for subviews(UIView s), this will get triggered. You can disable the scroll of UIScrollView and can enable it after -touchesEnded.Inform
T
3

If I'm not mistaken, your main scroll view contains another scroll view which is a parent of line chart. In that case you can use UIScrollViewDelegate protocol methods. Just disable main scroll view when you start scrolling child view.

- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
  if(scrollView==self.lineChartParent)
    self.mainScrollView.scrollingEnabled = NO;
}

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
  if(scrollView==self.lineChartParent)
    self.mainScrollView.scrollingEnabled = YES;
}
Trombidiasis answered 24/11, 2014 at 10:17 Comment(2)
This should work..you can also assign tags for the two scrollviews and take action by checking the tags...as done here.Maravedi
This is a nice way. However, the lineChartParent is not a ScrollView so it will not react with the scroll actions. What a pity. But this is also a nice way. I will try to use this method next time. Great thanks.Weathersby

© 2022 - 2024 — McMap. All rights reserved.