【问题标题】:How to detect when a UIScrollView has finished scrolling In Swift如何在 Swift 中检测 UIScrollView 何时完成滚动
【发布时间】:2015-08-15 10:49:15
【问题描述】:

众所周知,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
}

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

【问题讨论】:

    标签: ios swift uiscrollview


    【解决方案1】:

    委托方法告诉你什么时候完成

    func scrollViewDidEndDecelerating(scrollView: UIScrollView) {
        self.stoppedScrolling()
    }
    
    func scrollViewDidEndDragging(scrollView: UIScrollView, willDecelerate decelerate: Bool) {
        if !decelerate {
            self.stoppedScrolling()
        }
    }
    
    func stoppedScrolling() {
        println("Scroll finished")
    }
    

    【讨论】:

    • 这在滚动没有减速到停止点的情况下不起作用,当用户抬起手指时可能会很好,所以你也可以考虑scrollViewDidEndDragging。
    • 还有scrollViewDidEndScrollingAnimation,我之前也没考虑过:)
    【解决方案2】:

    需要检查用户是否停止拖拽,停止拖拽后view是否还在减速:

    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
    }
    

    【讨论】:

    • 检查isDecelerating和检查参数decelerate有什么区别?
    【解决方案3】:

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

    【讨论】:

      【解决方案4】:

      有一个UIScrollViewDelegate 的方法可以用来检测(或者更好的说是“预测”)滚动是否真正完成:

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

      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
      }
      

      【讨论】:

        【解决方案5】:

        如果用户滚动缓慢,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
        }
        

        【讨论】:

          猜你喜欢
          • 2010-11-02
          • 2019-02-09
          • 2018-11-22
          • 1970-01-01
          • 2018-04-09
          • 2021-03-11
          • 1970-01-01
          • 1970-01-01
          • 2011-04-17
          相关资源
          最近更新 更多