web-dev-qa-db-fra.com

Vérification de la vitesse de l'iPhone UIScrollView

Je sais comment obtenir le contentOffset en mouvement pour un UIScrollView, quelqu'un peut-il m'expliquer comment obtenir un nombre réel qui représente la vitesse actuelle d'un UIScrollView pendant le suivi ou la décélération?

36
NoodleOfDeath

Ayez ces propriétés sur votre UIScrollViewDelegate

CGPoint lastOffset;
NSTimeInterval lastOffsetCapture;
BOOL isScrollingFast;

Ensuite, ayez ce code pour votre 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;
    }
}

Et à partir de cela, j'obtiens des pixels par milliseconde, ce qui est supérieur à 0,5, je me suis connecté aussi rapidement et tout ce qui est ci-dessous est enregistré comme lent.

Je l'utilise pour charger quelques cellules sur une vue tableau animée. Il ne défile pas si bien si je les charge lorsque l'utilisateur défile rapidement.

56
bandejapaisa

Il existe un moyen plus simple: vérifiez la reconnaissance des mouvements de panoramique de UISCrollview. Avec lui, vous pouvez obtenir la vitesse comme suit:

CGPoint scrollVelocity = [[_scrollView panGestureRecognizer] velocityInView:self];
82
karstux

Réponse @bandejapaisa convertie en Swift 2.2:

Propriétés utilisées par UIScrollViewDelegate:

var lastOffset:CGPoint? = CGPointMake(0, 0)
var lastOffsetCapture:NSTimeInterval? = 0
var isScrollingFast: Bool = false

Et la fonction 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

    }
}
14
Mat0

Pour un calcul de vitesse simple (toutes les autres réponses sont plus compliquées):

- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
    CGFloat scrollSpeed = scrollView.contentOffset.y - previousScrollViewYOffset;
    previousTableViewYOffset = scrollView.contentOffset.y;
}
11
Roland Keesom

Cela pourrait être utile

- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset
6
FunkyKat

2017 ...

C'est très facile à faire avec Swift/iOS moderne:

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

Bien sûr, vous voulez la vitesse en points par seconde, c'est ce que c'est.

Les humains traînent, disons, 200 à 400 points par seconde (sur les appareils de 2017).

1000 - 3000 est un lancer rapide.

Comme il ralentit jusqu'à un arrêt, 20 - 30 est courant.

Donc, très souvent, vous verrez du code comme celui-ci ..

    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
    }

C'est la base de "l'ingénierie d'écrémage" sur les mobiles. (Ce qui est un sujet vaste et difficile.)

Notez que ce n'est pas une solution d'écrémage complète; vous devez également prendre soin de cas inhabituels comme "il s'est arrêté" "l'écran vient de se fermer", etc., etc.

5
Fattie

Vous pouvez voir PageControl exemple de code sur la façon d'obtenir le contentOffset de scrollview.

La contentOffset en mouvement peut être obtenue à partir de la méthode UIScrollViewDelegate, nommée - (void)scrollViewDidScroll:(UIScrollView *)scrollView, en interrogeant scrollView.contentOffset. La vitesse actuelle peut être calculée par delta_offset et delta_time.

  • Delta_offset = current_offset - pre_offset;
  • Delta_time = current_time - pre_time;
3
AechoLiu

Voici une autre façon intelligente de le faire dans 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.
    }
}

Donc, si vous faites défiler verticalement, vous devez utiliser velocity.y et aussi si vous faites défiler horizontalement, vous devez utiliser velocity.x. Généralement, si la valeur est supérieure à 1 et inférieure à -1, elle représente un défilement généralement rapide. Vous pouvez donc modifier la vitesse comme vous le souhaitez. + value signifie défiler vers le haut et -value signifie défiler vers le bas.

1
Chathuranga Silva