2010-09-15 6 views
32

Ich weiß, wie man den contentOffset auf Bewegung für einen UIScrollView bekommt, kann mir jemand erklären, wie ich eine tatsächliche Zahl bekommen kann, die die aktuelle Geschwindigkeit eines UIScrollView darstellt, während es verfolgt oder verlangsamt?iPhone UIScrollView Geschwindigkeitstest

+0

Keine große Sache, aber ich habe die moderne Lösung für diese sehr alte Frage auf den Boden. – Fattie

Antwort

51

haben diese Eigenschaften auf Ihrem UIScrollViewDelegate

CGPoint lastOffset; 
NSTimeInterval lastOffsetCapture; 
BOOL isScrollingFast; 

Dann diesen Code für Ihre scrollViewDidScroll haben:

- (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; 
    } 
} 

Und von dieser ich bin Pixel pro Millisekunde bekommen, die, wenn sie größer ist als 0,5, ich habe so schnell geloggt, und irgendetwas darunter wird als langsam protokolliert.

Ich benutze dies zum Laden einiger Zellen in einer Tabellenansicht animiert. Es scrollt nicht so gut, wenn ich sie lade, wenn der Benutzer schnell scrollt.

+0

Danke dafür. Hilfreich :) – Accatyyc

+1

brilliant, das war genau das, was ich plante. – jfisk

+4

danke für eine nette Lösung, die einzige Sache, die ich ändern würde, ersetzen Sie 0.1 mit 'captureInterval' const und dann verwenden Sie es auch in der Berechnung von' scrollSpeedNotAbs', um die Lesbarkeit des Algorithmus zu erhöhen (weil das Gehirn auf '* 10' stoppt, weil allgemeine Formel der Geschwindigkeit ist Abstand/Zeit). – zubko

3

Sie können PageControl Beispielcode sehen, wie Sie den ContentOffset von scrollview erhalten.

Die contentOffset auf Bewegung kann durch Abfragen von scrollView.contentOffsetUIScrollViewDelegate Methode, genannt - (void)scrollViewDidScroll:(UIScrollView *)scrollView, erhalten werden. Die aktuelle Geschwindigkeit kann mit delta_offset und delta_time berechnet werden.

  • Delta_offset = aktueller_offset - pre_offset;
  • Delta_zeit = aktuelle_zeit - vor_zeit;
+0

Oh, ich habe so eine Echtzeit-Geschwindigkeit mit Abstand über Zeit Ich nehme an –

+1

Die aktuelle Zeit kann durch CACurrentMediaTime() im QuartzCore-Framework erhalten werden. Dann können Sie die Geschwindigkeit nach Entfernung und Zeit berechnen. – AechoLiu

70

Es gibt einen einfacheren Weg: Überprüfen Sie die Pan Gestenerkennung des UISCrollview. Mit ihm können Sie die Geschwindigkeit erhalten wie so:

CGPoint scrollVelocity = [[_scrollView panGestureRecognizer] velocityInView:self]; 
+22

Handlich! Der einzige Nachteil ist, dass 'scrollVelocity' sofort nachdem der Benutzer den Finger gehoben hat, 0.0f ist (weil dadurch die Schwenkgeste beendet wird). Es ist also ein guter Weg, um die Geschwindigkeit zu messen, während der Scrollview gezogen wird, funktioniert aber nicht, wenn der Scroll-Bildschirm gedreht wird. –

+2

..und natürlich ist der panGestureRecognizer nur in iOS 5 verfügbar. – bandejapaisa

+0

ist die Scrollgeschwindigkeit ein Punkt, weil sie vertikale und horizontale Geschwindigkeiten aufzeichnet? –

9

Für eine einfache Geschwindigkeitsberechnung (Alle anderen Antworten sind komplizierter):

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

Das war genau das, was ich brauchte, danke ! – Giovanni

+0

Das hat mir auch geholfen, danke! Andere Leute könnten überlegen, eine fabsf() hinein zu werfen, nur um den absoluten Wert zu erhalten. – Andrew

+1

Sie müssen die Zeit berücksichtigen, sonst wird die Geschwindigkeit jittern. –

6

sein kann dies hilfreich sein würde

- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset 
+0

möchte erwähnen, dies ist ein Beispiel aus Geschwindigkeitsausgabe: '(0.0, -5.35356)'. Scrolle um die y-Achse, 5.35 .. -> 15 Punkte pro 'scrollViewDidScroll' Aufruf :) Also, 5 ist sehr schnell. –

9

Converted @bandejapaisa Antwort auf Swift 2.2:

Eigenschaften von UIScrollViewDelegate verwendet:

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

Und die scrollViewDidScroll Funktion:

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 

    } 
} 
0

Hier ist eine weitere intelligente Art und Weise dies in SWIFT zu tun: -

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. 
    } 
} 

Wenn Sie also vertikal Sie Scrollen sollten Sie velocity.y verwenden und wenn Sie horizontal scrollen, sollten Sie velocity.x verwenden. Im Allgemeinen, wenn der Wert größer als 1 und kleiner als -1 ist, handelt es sich um ein allgemein schnelles Scrollen. So können Sie die Geschwindigkeit ändern, wie Sie möchten. + Wert bedeutet Scrollen nach oben und -Wert bedeutet Scrollen nach unten.

+0

Wie stelle ich die Geschwindigkeit ein? –

+0

Was meinst du? :) –

+0

Sie sagten in Ihrer Antwort 'So können Sie die Geschwindigkeit ändern, wie Sie wollen'. Also frage ich mich, wie änderst du die Geschwindigkeit der Schriftrolle? –

1

2017 ...

Es ist sehr einfach, dies mit moderner Swift/iOS zu tun:

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

Natürlich können Sie die Geschwindigkeit in Punkten pro Sekunde wollen, das ist es, was das ist.

Menschen ziehen bei sagen 200 - 400 pps (auf 2017 Geräten).

1000 - 3000 ist ein schneller Wurf.

Während es bis zum Stillstand verlangsamt, ist 20-30 üblich.

So sehr oft werden Sie Code wie diesen sehen ..

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 
    } 

Dies ist die Grundlage für "Engineering Skimming" auf dem Handy. (Was ein großes und schwieriges Thema ist.)

Beachten Sie, dass das keine komplette Skimming-Lösung ist; Sie müssen auch für ungewöhnliche Fälle kümmern wie "es hat aufgehört" "der Bildschirm gerade geschlossen" etc.

Verwandte Themen