You can't get better precision than the one provided by contentOffset
. You could calculate velocity using regular ds/dt
equation:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
static CGFloat prevPos = 0.0; //you can store those in iVars
static NSTimeInterval prevTime = 0.0;
CGFloat newPos = scrollView.contentOffset.y;
NSTimeInterval newTime = [NSDate timeIntervalSinceReferenceDate];
double v = (newPos - prevPos)/(newTime - prevTime);
prevPos = newPos;
prevTime = newTime;
}
However, if you are feeling extremely hacky, and you want you code to be unsafe, you can peek into UIScrollView
's velocity iVars directly by using this category
@interface UIScrollView(UnsafeVelocity)
- (double) unsafeVerticalVelocty;
@end
@implementation UIScrollView(UnsafeVelocity)
- (double) unsafeVerticalVelocty
{
double returnValue = 0.0;
id verticalVel = nil;
@try {
verticalVel = [self valueForKey:@"_verticalVelocity"];
}
@catch (NSException *exception) {
NSLog(@"KVC peek failed!");
}
@finally {
if ([verticalVel isKindOfClass:[NSNumber class]]) {
returnValue = [verticalVel doubleValue];
}
}
return returnValue;
}
@end
To get horizontal velocity replace _verticalVelocity
with _horizontalVelocity
. Notice, that the values you will get seem to be scaled differently. I repeat once more: while this is (probably) the best value of velocity you can get, it is very fragile and not future-proof.