Я знаю, как получить contentOffset для движения для UIScrollView, может кто-нибудь объяснить мне, как я могу получить фактическое число, которое представляет текущую скорость UIScrollView во время отслеживания или замедления?
Проверка UIScrollView iPhone
Ответ 1
Введите эти свойства в свой UIScrollViewDelegate
CGPoint lastOffset;
NSTimeInterval lastOffsetCapture;
BOOL isScrollingFast;
Затем введите этот код для вашего 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;
}
}
И из этого я получаю пиксели за миллисекунду, а если больше 0,5, я регистрировался так же быстро, и все, что ниже, регистрируется как медленное.
Я использую это для загрузки некоторых ячеек в анимированном виде таблицы. Он не прокручивается так хорошо, если я загружаю их, когда пользователь быстро прокручивается.
Ответ 2
Есть более простой способ: проверить распознаватель жестов в UISCrollview. С его помощью вы можете получить скорость так:
CGPoint scrollVelocity = [[_scrollView panGestureRecognizer] velocityInView:self];
Ответ 3
Для простого вычисления скорости (все остальные ответы сложнее):
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
CGFloat scrollSpeed = scrollView.contentOffset.y - previousScrollViewYOffset;
previousTableViewYOffset = scrollView.contentOffset.y;
}
Ответ 4
Converted @bandejapaisa ответ на Swift 2.2:
Свойства, используемые UIScrollViewDelegate:
var lastOffset:CGPoint? = CGPointMake(0, 0)
var lastOffsetCapture:NSTimeInterval? = 0
var isScrollingFast: Bool = false
И функция 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
}
}
Ответ 5
Может быть, это было бы полезно
- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset
Ответ 6
Вы можете увидеть PageControl пример кода о том, как получить contentOffset для scrollview.
При перемещении contentOffset
можно получить метод UIScrollViewDelegate
, названный - (void)scrollViewDidScroll:(UIScrollView *)scrollView
, запросив scrollView.contentOffset
. Текущую скорость можно рассчитать по delta_offset и delta_time.
- Delta_offset = current_offset - pre_offset;
- Delta_time = current_time - pre_time;
Ответ 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)")
Конечно, вам нужна скорость в точках в секунду, что и есть.
Люди перетаскивают, скажем, 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
}
Это основа для "skimming engineering" на мобильных телефонах. (Это большая и трудная тема.)
Обратите внимание, что это не полное решение для скиминга; вы также должны заботиться о таких необычных случаях, как "он остановился", "экран закрыт" и т.д.
Ответ 8
Вот еще один умный способ сделать это в SWIFT: -
func scrollViewWillEndDragging(scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
if velocity.y > 1.0 || velocity.y < -1.0 && self.sendMessageView.isFirstResponder() {
// Somthing you want to do when scrollin fast.
// Generally fast Vertical scrolling.
}
}
Итак, если вы прокручиваете вертикально, вы должны использовать speed.y, а также если вы прокручиваете по горизонтали, вы должны использовать speed.x. Обычно, если значение больше 1 и меньше -1, оно представляет собой быструю прокрутку. Таким образом, вы можете изменить скорость, как хотите. + означает, что прокрутка вверх и -значение означает прокрутку вниз.