Подтвердить что ты не робот

Проверка UIScrollView iPhone

Я знаю, как получить contentOffset для движения для UIScrollView, может кто-нибудь объяснить мне, как я могу получить фактическое число, которое представляет текущую скорость UIScrollView во время отслеживания или замедления?

4b9b3361

Ответ 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, оно представляет собой быструю прокрутку. Таким образом, вы можете изменить скорость, как хотите. + означает, что прокрутка вверх и -значение означает прокрутку вниз.