Как определить, когда UIScrollView закончил прокрутку в Swift

было, по всем отзывам, отличное решение этой проблемы в Obj-C, представленное Эшли смарт (как определить, когда UIScrollView закончил прокрутку).

-(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 в 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
}

но я все еще не сложить вместе. Любой помочь?

5 ответов


метод делегата сообщает вам, когда закончено

func scrollViewDidEndDecelerating(scrollView: UIScrollView) {
    println("Scroll finished")
}

на scrollViewDidEndDecelerating не будет вызываться, если пользователь прокручивается медленно. Вот Эшли смарт asnwear в Swift

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
}

существует метод UIScrollViewDelegate который можно использовать для обнаружения (или лучше сказать "предсказать"), когда прокрутка действительно закончена:

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

of UIScrollViewDelegate который можно использовать для обнаружения (или лучше сказать "предсказать"), когда прокрутка действительно закончена.

в моем случае я использовал его с горизонтальной прокруткой следующим образом (в 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
}

вам нужно проверить, прекратил ли пользователь перетаскивание и если представление все еще замедляется после того, как пользователь перестал перетаскивать:

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
}

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)
    }