Sensitivity/Scroll speed of UIScrollView with paging

Viewed 33054

I want UIScrollView to scroll fast after fast sweep, like this. Although, when paging is turned on, the scroll works one page at a time. Is it possible to scroll fast, when paging is enabled with a flick of a finger without manually implementation using gesture recognizers?

3 Answers

I think we can set scrollView.userInteractionEnabled = NO when our finger touch it. And then when the animation is stop ,open it .It works for me. Hope it will help you.

-(void)scrollViewWillBeginDragging:(UIScrollView *)scrollView{
    scrollView.userInteractionEnabled = NO;
}

// at the end of scroll animation, reset the boolean used when scrolls originate from the UIPageControl
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
    scrollView.userInteractionEnabled = YES;
}

I have a solution that allows for fast scrolling, and snaps when the speed is slow, it looks like this: https://imgur.com/a/r7Etltu

We need 4 variables:

var dragging = false
var lastOffset: CGPoint = .zero
var lastOffsetCapture: TimeInterval = .zero
var isScrollingFast: Bool = false

We need a helper function:

extension UIScrollView {
    var currentPage:Int{
        return Int((self.contentOffset.x+(0.5*self.frame.size.width))/self.frame.width)
    }
}

Then we need delegate methods:

func scrollViewDidScroll(_ scrollView: UIScrollView) {
    let currentOffset = scrollView.contentOffset
    let currentTime = Date.timeIntervalSinceReferenceDate
    let timeDiff = currentTime - lastOffsetCapture
    let captureInterval = 0.1
        
    if timeDiff > captureInterval {
        let distance = currentOffset.x - lastOffset.x 
            let scrollSpeedNotAbs = (distance * 10) / 1000
            let scrollSpeed = fabsf(Float(scrollSpeedNotAbs))
            
            if scrollSpeed > 0.3 {
                isScrollingFast = true
            } else {
                if isScrollingFast && !dragging && scrollSpeed > 0.1 {
                    isScrollingFast = false
                    snapCard()
                }
            }
            lastOffset = currentOffset
            lastOffsetCapture = currentTime
        }
    }
    
    func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
        dragging = true
    }
    
    func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
        dragging = false
        let currentPage = scrollView.currentPage
        let pageSize = YOUR PAGE SIZE
        if velocity.x == 0 {
            let rightOfCenter = scrollView.contentOffset.x - currentPage*pageSize > 0
            snapCard(force: true, moveRight: rightOfCenter)
            return
        }
        if fabsf(Float(velocity.x)) < 0.3 {
            snapCard(force: true, moveRight: velocity.x > 0)
        }
    }
    
    func snapCard(force: Bool = false, moveRight: Bool = true) {
        let currentPage = scrollView.currentPage
        let pageSize = YOUR PAGE SIZE
        if !force {
            scrollView.setContentOffset(CGPoint(x: currentPage * pageSize, y: 0), animated: true)
        } else {
            if currentPage != YOUR NUM PAGES -1 {
                scrollView.setContentOffset(CGPoint(x: pageSize *(currentPage + (moveRight ? 1 : -1)), y: 0), animated: true)
            }
        }
    }
Related