I am trying to implement a scroll view that snaps to points while scrolling.
All the posts here I've seen about snapping to a point 'after' the user has ended dragging the scroll. I want to make it snap during dragging.
So far I have this to stop the inertia after dragging and it works fine:
func scrollViewWillEndDragging(scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
targetContentOffset.memory = scrollView.contentOffset
}
I tried this but not working as desired:
var scrollSnapHeight : CGFloat = myScrollView.contentSize.height/10
scrollViewDidScroll:
func scrollViewDidScroll(scrollView: UIScrollView) {
let remainder : CGFloat = scrollView.contentOffset.y % scrollSnapHeight
var scrollPoint : CGPoint = scrollView.contentOffset
if remainder != 0 && scrollView.dragging
{
if self.lastOffset > scrollView.contentOffset.y //Scrolling Down
{
scrollPoint.y += (scrollSnapHeight - remainder)
NSLog("scrollDown")
}
else //Scrolling Up
{
scrollPoint.y -= (scrollSnapHeight - remainder)
}
scrollView .setContentOffset(scrollPoint, animated: true)
}
self.lastOffset = scrollView.contentOffset.y;
}
This approach is going to enable / disable
scrollEnabled
property ofUIScrollView
.When scrollView scrolls outside the given
scrollSnapHeight
, makescrollEnabled
tofalse
. That will stop the scrolling. Then make scrolling enable again for the next drag.Subclass UIScrollView/UICollectionView
This solution does not require you lift your finger in order to unsnap and works while scrolling. If you need it for vertical scrolling and not horizontal scrolling just swap the x's with y's.
Set snapPoint to the content offset where you want the center of the snap to be.
Set snapOffset to the radius you want around the snapPoint for where snapping should occur.
If you need to know if the scrollView has snapped, just check the isSnapped variable.