iPhone UIScrollView速度检查

Noo*_*ath 35 iphone scroll uiscrollview

我知道如何在UIScrollView上运行contentOffset,有人可以向我解释如何在跟踪或减速时获得表示UIScrollView当前速度的实际数字吗?

小智 79

有一种更简单的方法:检查UISCrollview的平移手势识别器.有了它,你可以得到这样的速度:

CGPoint scrollVelocity = [[_scrollView panGestureRecognizer] velocityInView:self];
Run Code Online (Sandbox Code Playgroud)

  • 便利!唯一的缺点是,在用户抬起手指后,"scrollVelocity"将立即为0.0f(因为这会结束平移手势).因此,在拖动滚动视图时,这是一种测量速度的好方法,但如果轻弹则不起作用. (27认同)
  • ..当然,panGestureRecognizer仅在iOS 5及更高版本中公开. (2认同)

ban*_*isa 56

在UIScrollViewDelegate上拥有这些属性

CGPoint lastOffset;
NSTimeInterval lastOffsetCapture;
BOOL isScrollingFast;
Run Code Online (Sandbox Code Playgroud)

然后为您的scrollViewDidScroll提供此代码:

- (void) scrollViewDidScroll:(UIScrollView *)scrollView {    
    CGPoint currentOffset = scrollView.contentOffset;
    NSTimeInterval currentTime = [NSDate timeIntervalSinceReferenceDate];

    NSTimeInterval timeDiff = currentTime - lastOffsetCapture;
    if(timeDiff > 0.1) {
        CGFloat distance = currentOffset.y - lastOffset.y;
        //The multiply by 10, / 1000 isn't really necessary.......
        CGFloat scrollSpeedNotAbs = (distance * 10) / 1000; //in pixels per millisecond

        CGFloat scrollSpeed = fabsf(scrollSpeedNotAbs);
        if (scrollSpeed > 0.5) {
            isScrollingFast = YES;
            NSLog(@"Fast");
        } else {
            isScrollingFast = NO;
            NSLog(@"Slow");
        }        

        lastOffset = currentOffset;
        lastOffsetCapture = currentTime;
    }
}
Run Code Online (Sandbox Code Playgroud)

从这里我得到每毫秒的像素,如果大于0.5,我的记录速度很快,下面的任何内容记录都很慢.

我使用它来加载动态表视图上的一些单元格.如果我在用户快速滚动时加载它,它就不会滚动得那么好.

  • 感谢一个很好的解决方案,我唯一要改变的是用`captureInterval` const替换0.1,并且在计算`scrollSpeedNotAbs`时也使用它来增加算法的可读性(因为大脑停在`*10`因为一般速度公式是距离/时间). (4认同)
  • scrollview/collectionView的精彩扩展!救了我的一天:-) (2认同)

Mat*_*at0 13

转换@bandejapaisa回答Swift 2.2:

UIScrollViewDelegate使用的属性:

var lastOffset:CGPoint? = CGPointMake(0, 0)
var lastOffsetCapture:NSTimeInterval? = 0
var isScrollingFast: Bool = false
Run Code Online (Sandbox Code Playgroud)

而scrollViewDidScroll函数:

func scrollViewDidScroll(scrollView: UIScrollView) {

    let currentOffset = scrollView.contentOffset
    let currentTime = NSDate().timeIntervalSinceReferenceDate
    let timeDiff = currentTime - lastOffsetCapture!
    let captureInterval = 0.1

    if(timeDiff > captureInterval) {

        let distance = currentOffset.y - lastOffset!.y     // calc distance
        let scrollSpeedNotAbs = (distance * 10) / 1000     // pixels per ms*10
        let scrollSpeed = fabsf(Float(scrollSpeedNotAbs))  // absolute value

        if (scrollSpeed > 0.5) {
            isScrollingFast = true
            print("Fast")
        }
        else {
            isScrollingFast = false
            print("Slow")
        }

        lastOffset = currentOffset
        lastOffsetCapture = currentTime

    }
}
Run Code Online (Sandbox Code Playgroud)


Rol*_*som 11

对于简单的速度计算(所有其他答案都更复杂):

- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
    CGFloat scrollSpeed = scrollView.contentOffset.y - previousScrollViewYOffset;
    previousTableViewYOffset = scrollView.contentOffset.y;
}
Run Code Online (Sandbox Code Playgroud)

  • 你需要考虑时间,否则速度会抖动. (3认同)

Fat*_*tie 7

2017...

使用现代 Swift/iOS 很容易做到这一点:

var previousScrollMoment: Date = Date()
var previousScrollX: CGFloat = 0

func scrollViewDidScroll(_ scrollView: UIScrollView) {
        
    let d = Date()
    let x = scrollView.contentOffset.x
    let elapsed = Date().timeIntervalSince(previousScrollMoment)
    let distance = (x - previousScrollX)
    let velocity = (elapsed == 0) ? 0 : fabs(distance / CGFloat(elapsed))
    previousScrollMoment = d
    previousScrollX = x
    print("vel \(velocity)")
Run Code Online (Sandbox Code Playgroud)

当然,您想要以每秒点数为单位的速度,这就是速度。

人类以 200 - 400 pps 的速度拖动(在 2017 设备上)。

1000 - 3000 是一个快速的投掷。

当它减速到停止时,20 - 30 是常见的。

所以很多时候你会看到这样的代码..

    if velocity > 300 {
    
        // the display is >skimming<
        some_global_doNotMakeDatabaseCalls = true
        some_global_doNotRenderDiagrams = true
    }
    else {
    
        // we are not skimming, ok to do calculations
        some_global_doNotMakeDatabaseCalls = false
        some_global_doNotRenderDiagrams = false
    }
Run Code Online (Sandbox Code Playgroud)

这是在手机上进行“略读工程”的基础。(这是一个大而难的话题。)

请注意,这不是一个完整的略读解决方案;您还必须注意不寻常的情况,例如“它已停止”“屏幕刚刚关闭”等。


Fun*_*Kat 6

可能这会有所帮助

- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset
Run Code Online (Sandbox Code Playgroud)