Controllo velocità UIScrollView per iPhone

So come ottenere contentOffset in movimento per un UIScrollView, qualcuno può spiegarmi come ottenere un numero reale che rappresenti la velocità attuale di un UIScrollView mentre sta monitorando o decelerando?

Avere queste proprietà sul tuo UIScrollViewDelegate

CGPoint lastOffset; NSTimeInterval lastOffsetCapture; BOOL isScrollingFast; 

Quindi disponi di questo codice per 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; } } 

E da questo sto ricevendo i pixel per millisecondo, che se è maggiore di 0.5, ho registrato il più velocemente ansible, e qualsiasi cosa sotto è registrata come lenta.

Lo uso per caricare alcune celle su una vista tabella animata. Non scorre così bene se li carico quando l’utente sta scorrendo velocemente.

C’è un modo più semplice: controlla il riconoscimento del gesto di panoramica pan di UISCrollview. Con esso, puoi ottenere la velocità in questo modo:

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

Per un semplice calcolo della velocità (tutte le altre risposte sono più complicate):

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

Conversione @bandejapaisa risposta a Swift 2.2:

Proprietà utilizzate da UIScrollViewDelegate:

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

E la funzione 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 } } 

Potrebbe essere questo sarebbe utile

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

Puoi vedere il codice di esempio di PageControl su come ottenere contentOffset di scrollview.

Il contentOffset in movimento può essere ottenuto dal metodo UIScrollViewDelegate , denominato - (void)scrollViewDidScroll:(UIScrollView *)scrollView , interrogando scrollView.contentOffset . La velocità corrente può essere calcasting da delta_offset e delta_time.

  • Delta_offset = current_offset – pre_offset;
  • Delta_time = current_time – pre_time;

2017 …

È molto facile farlo con i moderni 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)") 

Certo che vuoi la velocità in punti al secondo, che è quello che è.

Gli esseri umani trascinano a dire 200 – 400 pps (sui dispositivi del 2017).

1000 – 3000 è un tiro veloce.

Mentre rallenta fino a fermarsi, 20 – 30 è comune.

Quindi molto spesso vedrai un codice come questo ..

  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 } 

Questa è la base per "skimming engineering" sui cellulari. (Che è un argomento ampio e difficile).

Si noti che non è una soluzione di skimming completa; devi anche preoccuparti di casi insoliti come "si è fermato" "lo schermo appena chiuso" ecc ecc.

Ecco un altro modo intelligente per farlo in SWIFT: –

 func scrollViewWillEndDragging(scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer) { if velocity.y > 1.0 || velocity.y < -1.0 && self.sendMessageView.isFirstResponder() { // Somthing you want to do when scrollin fast. // Generally fast Vertical scrolling. } } 

Quindi se stai scorrendo verticalmente dovresti usare velocity.y e anche se stai scorrendo orizzontalmente dovresti usare velocity.x. Generalmente se il valore è superiore a 1 e inferiore a -1, rappresenta generalmente uno scorrimento veloce. Quindi puoi cambiare la velocità come preferisci. + valore significa scorrere verso l'alto e -valore significa scorrere verso il basso.