如何检测 UIScrollView 何时完成滚动 In Swift

How to detect when a UIScrollView has finished scrolling In Swift

从各方面来看,Ashley Smart (How to detect when a UIScrollView has finished scrolling) 在 Obj-C 中提出了一个很好的解决这个问题的方法。

-(void)scrollViewDidScroll:(UIScrollView *)sender 
{   
[NSObject cancelPreviousPerformRequestsWithTarget:self];
    //ensure that the end of scroll is fired.
    [self performSelector:@selector(scrollViewDidEndScrollingAnimation:) withObject:nil afterDelay:0.3]; 

...
}

-(void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView
{
    [NSObject cancelPreviousPerformRequestsWithTarget:self];
...
}

但是,我需要一个解决方案,在 Swift。

看来,由 Matt (dispatch_after - GCD in swift?) 贡献的优秀延迟函数可能会有所帮助。

func delay(delay:Double, closure:()->()) {
    dispatch_after(
        dispatch_time(
            DISPATCH_TIME_NOW,
            Int64(delay * Double(NSEC_PER_SEC))
        ),
        dispatch_get_main_queue(), closure)
}

并实施为...

delay(0.4) {
    // do stuff
}

但我还没有把它放在一起。有什么帮助吗?

委托方法在完成时告诉您

func scrollViewDidEndDecelerating(scrollView: UIScrollView) {
    self.stoppedScrolling()
}

func scrollViewDidEndDragging(scrollView: UIScrollView, willDecelerate decelerate: Bool) {
    if !decelerate {
        self.stoppedScrolling()
    }
}

func stoppedScrolling() {
    println("Scroll finished")
}

如果用户滚动缓慢,则不会调用 scrollViewDidEndDecelerating。这是 Swift

中的 Ashley Smart asnwear
func scrollViewDidScroll(_ scrollView: UIScrollView) {
    NSObject.cancelPreviousPerformRequests(withTarget: self)
    perform(#selector(UIScrollViewDelegate.scrollViewDidEndScrollingAnimation), with: nil, afterDelay: 0.3)
}

func scrollViewDidEndScrollingAnimation(_ scrollView: UIScrollView) {
    NSObject.cancelPreviousPerformRequests(withTarget: self)
// Call your function here
}

您需要检查用户是否停止拖动以及用户停止拖动后视图是否仍在减速:

func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
    if collectionView.isDecelerating == false {
        // Perform whichever function you desire for when scrolling has stopped
    }
}

func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
    // Perform whichever function you desire for when scrolling has stopped
}

有一种方法 UIScrollViewDelegate 可用于检测(或更好地说 'predict')滚动何时真正完成:

func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>)

of UIScrollViewDelegate 可用于检测(或更好地说 'predict')滚动何时真正完成。

在我的例子中,我将它与水平滚动一起使用,如下所示(在 Swift 3 中):

func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
    perform(#selector(self.actionOnFinishedScrolling), with: nil, afterDelay: Double(velocity.x))
}
func actionOnFinishedScrolling() {
    print("scrolling is finished")
    // do what you need
}

Swift 版本:

注意:您提到的答案是一种可能的解决方案,因情况而异

func scrollViewDidScroll(_ scrollView: UIScrollView) {

        // YOUR CODE........
        NSObject.cancelPreviousPerformRequests(withTarget: self)
        self.perform(#selector(scrollViewDidEndScrollingAnimation(_:)), with: scrollView, afterDelay: 0.3)
    }

    func scrollViewDidEndScrollingAnimation(_ scrollView: UIScrollView) {


        // YOUR CODE ........
        NSObject.cancelPreviousPerformRequests(withTarget: self)
    }