Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I programmatically force-stop scrolling in a UIScrollView?

Note: The answer given here doesn't work for me.

I have a UIScrollView (not a table view, just a custom thing), and when the user takes certain actions, I want to kill any scrolling (dragging or deceleration) inside the view. I've tried doing e.g. this:

[scrollView scrollRectToVisible:CGRectInset([scrollView bounds], 10, 10) animated:NO]; 

on the theory that, given a rect that's already known visible, the scrolling will just stop where it is, but it turns out that this doesn't have any effect-- apparently the scroll view sees that the given rect is in bounds and takes no action. I can get the scroll to stop, if I give a rect that is definitely outside the currently-visible bounds, but inside the contentSize of the view. This seems to halt the view as expected... but also causes it to jump to some other location. I could probably do a little playing around at the margins to get this to work reasonably OK, but does anyone know of a clean way to halt a scroll view that's doing its thing?

Thanks.

like image 448
Ben Zotto Avatar asked Aug 04 '10 23:08

Ben Zotto


People also ask

How do I disable scroll in react native?

To enable or disable scrolling on FlatList with React Native, we can set the scrollEnabled prop. to set the scrollEnabled prop to false to disable scrolling on the FlatList.

How do I stop singleChildScrollView from scrolling?

You can use the following code in your singleChildScrollView. physics: NeverScrollableScrollPhysics(), It stops it from being able to scroll.


2 Answers

I played with your original solution a bit, and this seems to work just fine. I think you almost had it, but you were just offsetting the rect that you used too much, and forgot that you could just scroll the rect straight back to the original rect.

The generalized solution for any scrolling action is this:

- (void)killScroll  {     CGPoint offset = scrollView.contentOffset;     offset.x -= 1.0;     offset.y -= 1.0;     [scrollView setContentOffset:offset animated:NO];     offset.x += 1.0;     offset.y += 1.0;     [scrollView setContentOffset:offset animated:NO]; } 

[Edit] As of iOS 4.3 (and possibly earlier) this also appears to work

- (void)killScroll  {     CGPoint offset = scrollView.contentOffset;     [scrollView setContentOffset:offset animated:NO]; } 
like image 156
David Liu Avatar answered Sep 27 '22 23:09

David Liu


The generic answer is, that [scrollView setContentOffset:offset animated:NO] is not the same as [scrollView setContentOffset:offset] !

  • [scrollView setContentOffset:offset animated:NO] actually stops any running animation.
  • [scrollView setContentOffset:offset] doesn't stop any running animation.
  • Same for scrollView.contentOffset = offset: doesn't stop any running animation.

That's not documented anywhere, but that's the behavior as tested on iOS 6.1 & iOS 7.1 - probably also before.

So the solution to stop a running animation / deceleration is simple as that:

[scrollView setContentOffset:scrollView.contentOffset animated:NO]; 

Basically what David Liu said in his edited answer. But I wanted to make clear, that these two APIs are NOT the same.

Swift 3:

scrollView.setContentOffset(scrollView.contentOffset, animated:false) 
like image 31
calimarkus Avatar answered Sep 27 '22 22:09

calimarkus