I have a UIScrollView that is scrolling a fairly large UIView.
At certain times I want to limit the area the user can scroll around in. For example, I may only want to allow them to view the bottom quarter of the view.
I am able to limit the area by overriding scrollViewDidScroll and then calling setContentOffset if the view has scrolled too far. But this way I can't get it bounce back as smoothly as the UIScrollView can naturally do when scrolling beyond the bounds of the UIView.
Is there a better way to limit the scrollable area in a UIScrollView?
a small improvement on Yoko's answer in Swift 4 will be
which will make the scrollview animate really similar to what its supposed to do. The slower drag when you are in the "bounce" area will not work and animation duration has to depend on the distance (not constant like here) if you want to be exact. You can also try to do this logic in
scrollViewDidScroll
and see how it differs. The key thing is thatsetContentOffset(_:,animated:)
has to be with animated: false so that theUIViewPropertyAnimator
's block can capture it and animate itAnother approach is to override the
UIScrollView
's method:- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
.Returning
YES
will allow the user to scroll. ReturningNO
will not.NOTE: This will disable all touches to any views imbedded inside the
UIScrollView
thatpointInside
returnsNO
to. Useful if the area you don't want to scroll from doesn't have any interaction.This example only allows the
UIScrollView
to scroll when the user is scrolling over aUITableView
. (AUITableView
and twoUIViews
are imbedded inside theUIScrollView
)I would change the contentSize property of the scroll view to the size of the area you want the user to be able to scroll around in and adjust the frame.origin of the subview such the upper left boundary you want appears at (0, 0) relative to the scroll view. For example, if your view is 800 points tall and you want to show the bottom quarter, set the height of contentSize to 200 and set the y component of view.frame.origin to -600.
I've found something that works for me. It let's you scroll to point 0,0 but no further:
You could do the same for top, bottom or right (x or y)