UIScrollView in UIScrollView, how to keep a smooth transition when scrolling between two

I have the following layout (see below), which for most circumstances works just fine. The user can scroll in the blue UIScrollView (which for all purposes and tasks is a UITableView , but this question summarizes this), and then when they have reached the end of this scroll, they can start scrolling again (they have to move their finger and again because the inner scrolling through the rubber bands otherwise), and scrolling β€œsuper” starts scrolling, showing the rest of the image.

This is the whole (they have to take their finger away again, because the internal scrolling scrolls through the gum otherwise), which I do not want. Ideally, as soon as the content of the UIScrollView reaches the end of its content, I want the supervisor to capture the scroll immediately so that the internal scroll view is not an elastic.

The same thing happens when the user scrolls; when the red scrollview reaches the top of its contents, I want the inner blue scroll to start scrolling right, rather than the red scroll that looks at the top.

Screen layout; UIScrollView + UIImageView within a UIScrollView

Any idea how? I can determine when the scroll views reached the end of their content, but I'm not sure how to apply this knowledge to achieve the effect that I use. Thanks.

 // Inner (blue) scroll view bounds checking if (scrollView.contentOffset.y + scrollView.frame.size.height > scrollView.contentSize.height) { ... } // Outer (red) scroll view bounds checking if (scrollView.contentOffset.y < 0) { ... } 
+4
source share
1 answer

Yes. I have a great trick for you.

Instead of having its own red outlined appearance, scrollview makes it a normal UIView that fills the screen. In this view, lay out your scroll view (table view) and image as shown.

Place a scroll that fills the borders of the root view (i.e. also fills the screen) above all other scroll views and images. Set the content size of this view as the total height of the content of all the views you want to scroll. In other words, there is an invisible scrollview sitting on top of all your other views, and its content size height is the internal size of the size of the scrolling image (tableview) or image height.

The hierarchy should look like this:

enter image description here

Then this scroll at the top that you created with really high content size makes it a delegate to your controller. Implement scrollViewDidScroll and we will work with magic.

Scrollviews basically scroll, adjusting the origin using funky momentum formulas, etc. Therefore, in our scrollViewDidScroll method scrollViewDidScroll we simply adjust the boundaries of the base views:

 -(void)scrollViewDidScroll:(UIScrollView *)scrollView{ //the scroll view underneath (in the container view) will have a max content offset equal to the content height //but minus the bounds height CGFloat maxYOffsetForUnderScrollView = self.underScrollView.contentSize.height - self.underScrollView.bounds.size.height; CGRect scrolledBoundsForContainerView = self.view.bounds; if (scrollView.contentOffset.y <= maxYOffsetForUnderScrollView) { //in this scenario we are still within the content for the underScrollView //so we make sure the container view is scrolled to the top and set the offset for the contained scrollview self.containerView.bounds = scrolledBoundsForContainerView; self.underScrollview.contentOffset = scrollView.contentOffset; return; } //in this scenario we have scrolled throug the entirety of the contained scrollview //set its offset to the max and change the bounds of the container view to scroll everything else. self.underScrollView.contentOffset = CGPointMake(0, maxYOffsetForUnderScrollView); scrolledBoundsForContainerView.origin.y = scrollView.contentOffset.y - maxYOffsetForUnderScrollView; self.containerView.bounds = scrolledBoundsForContainerView; } 

You will find that since scrollViewDidScroll is called every frame of the animation, this artificially scrolling of hidden views looks really natural.

But wait! I can hear you talking. This scrollable top view now captures ALL strokes, and the gaze below it also needs to be touched. I have an interesting solution for this.

Set the scroll bar at the top so that the screen does not appear somewhere (i.e., set its frame off-screen, but the same size.), And then in your viewDidLoad method you add scrollview panGestureRecogniser to the main view. This will mean that you get a full increase in iOS scrolling and so on without actually displaying it on the screen. The hidden scroll view is now likely to be changed since its recognizing gesture sign will cause a call (they work differently with UIEvent handling), so you will need to delete it.

 - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. [self.view addGestureRecognizer:self.scrollview.panGestureRecognizer]; [self.underScrollview removeGestureRecognizer:self.underScrollView.panGestureRecognizer]; //further code to set up content sizes and stuff } 

I liked doing this, so the link to the sample project on github: https://github.com/joelparsons/multipleScrollers

EDIT:

To display the scroll bar for the top scroll when it is off the screen, no matter where you place it, you can set scrollIndicatorInsets to an insert created as follows:

 CGPoint scrollviewOrigin = self.scrollview.frame.origin; self.scrollview.scrollIndicatorInsets = UIEdgeInsetsMake(-scrollviewOrigin.y,0,scrollviewOrigin.y,scrollviewOrigin.x); 

* caution that scrollview should still be the correct height, but I'm sure you understand this idea.

And then, to draw a line outside the visible scroll borders, you must turn off the clips to the borders

 self.scrollview.clipsToBounds = NO; 
+11
source

Source: https://habr.com/ru/post/1443982/


All Articles