Domanda

Come posso testare se la vista a scorrimento è rimbalzante? C'è una notifica o qualcosa del genere quando il rimbalzo finisce?

È stato utile?

Soluzione

Sì ... controlla le specifiche UISCrollViewDelegate, implementa i metodi tra cui i due di seguito e imposta di conseguenza il delegato di UisCrollview:

// User stops dragging the table view.

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView
    willDecelerate:(BOOL)decelerate;

// Control slows to a halt after the user drags it

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView;

Probabilmente sarai più interessato a ScrollViewDidendDecelerating. Questi funzionano anche in UableView che è dove originariamente li ho trovati (UableView eredita da UisCrollView).

Altri suggerimenti

Ecco come ho rilevato se la vista a scorrimento è rimbalzante in orizzontale:

- (void)scrollViewDidScroll:(UIScrollView *)scrollView {

  if (scrollView.contentOffset.x < 0) {
    NSLog(@"bouncing left");
  }

  if (scrollView.contentOffset.x > (scrollView.contentSize.width - scrollView.frame.size.width)) {
    NSLog(@"bouncing right");
  }
}

Ho implementato l'estensione per UISCrollView per gestire questo per lo scorrimento verticale e orizzontale. Funzionerà anche con inset di contenuti diversi da zero e nel caso in cui il contenuto non sia abbastanza grande per coprire gli inserti di ScrollView:

Obiettivo-C

@interface UIScrollView (Bouncing)

@property (nonatomic, readonly) BOOL isBouncing;
@property (nonatomic, readonly) BOOL isBouncingTop;
@property (nonatomic, readonly) BOOL isBouncingLeft;
@property (nonatomic, readonly) BOOL isBouncingBottom;
@property (nonatomic, readonly) BOOL isBouncingRight;

@end

@implementation UIScrollView (Bouncing)

- (BOOL)isBouncing
{
    return self.isBouncingTop || self.isBouncingLeft || self.isBouncingBottom || self.isBouncingRight;
}

- (BOOL)isBouncingTop
{
    return self.contentOffset.y < - self.contentInset.top;
}

- (BOOL)isBouncingLeft
{
    return self.contentOffset.x < - self.contentInset.left;
}

- (BOOL)isBouncingBottom
{
    BOOL contentFillsScrollEdges = self.contentSize.height + self.contentInset.top + self.contentInset.bottom >= CGRectGetHeight(self.bounds);
    return contentFillsScrollEdges && self.contentOffset.y > self.contentSize.height - CGRectGetHeight(self.bounds) + self.contentInset.bottom;
}

- (BOOL)isBouncingRight
{
    BOOL contentFillsScrollEdges = self.contentSize.width + self.contentInset.left + self.contentInset.right >= CGRectGetWidth(self.bounds);
    return contentFillsScrollEdges && self.contentOffset.x > self.contentSize.width - CGRectGetWidth(self.bounds) + self.contentInset.right;
}

@end

Swift 3.0+

extension UIScrollView {
  var isBouncing: Bool {
    return isBouncingTop || isBouncingLeft || isBouncingBottom || isBouncingRight
  }
  var isBouncingTop: Bool {
    return contentOffset.y < -contentInset.top
  }
  var isBouncingLeft: Bool {
    return contentOffset.x < -contentInset.left
  }
  var isBouncingBottom: Bool {
    let contentFillsScrollEdges = contentSize.height + contentInset.top + contentInset.bottom >= bounds.height
    return contentFillsScrollEdges && contentOffset.y > contentSize.height - bounds.height + contentInset.bottom
  }
  var isBouncingRight: Bool {
    let contentFillsScrollEdges = contentSize.width + contentInset.left + contentInset.right >= bounds.width
    return contentFillsScrollEdges && contentOffset.x > contentSize.width - bounds.width + contentInset.right
  }
}

Per Rxswift Puoi semplicemente mappare scrollViewDidScroll insieme a isBouncing e filtrare con distinctUntilChanged.

Un emendamento minore al metodo di Justin, consentendo ContentIset:

if( scrollView.contentOffset.x < -scrollView.contentInset.left )
{
    NSLog( @"bounce left" );
}
if( scrollView.contentOffset.x > scrollView.contentSize.width - scrollView.frame.size.width + scrollView.contentInset.right )
{
    NSLog( @"bounce right" );
}

Vecchia domanda, ma ho appena incontrato un problema simile e volevo aggiungere che è una buona idea verificare anche che il contenuto delle visualizzazioni di scroll sia più grande del frame della vista scroll:

+ (BOOL) isScrollViewBouncing:(UIScrollView *)scrollView
{
    return scrollView.contentOffset.y > scrollView.contentSize.height - scrollView.frame.size.height
            && scrollView.contentSize.height > scrollView.frame.size.height;
}

Questo ora si assicura che la vista a scorrimento sia abbastanza grande da essere in uno stato di rimbalzo, in modo che se la vista a scorrimento è piccola non si valuta sempre al vero.

Saluti

Per quelli di voi che sarebbero in grado di "rimbalzare" verso il basso in uno scrollview per aggiornare il contenuto della vista. (E l'evento viene licenziato solo una volta.)

- (void)scrollViewDidEndDragging:(UIScrollView *)aScrollView
                  willDecelerate:(BOOL)decelerate{

    CGPoint offset = aScrollView.contentOffset;
    CGRect bounds = aScrollView.bounds;
    CGSize size = aScrollView.contentSize;
    UIEdgeInsets inset = aScrollView.contentInset;
    float y = offset.y + bounds.size.height - inset.bottom;
    float h = size.height;

    //Distance in points before update-event occur
    float reload_distance = 50;
    //
    if(y > h + reload_distance) {
        NSLog(@"load more rows");
    }
}

Usando la risposta di Glavid, ho aggiunto anche il rimbalzo sul fondo e ho aggiunto come categoria

#import "UIScrollView+Additions.h"

@implementation UIScrollView (Additions)

- (BOOL)isBouncing
{
    BOOL isBouncingBottom = self.contentOffset.y >= self.contentSize.height - self.frame.size.height
        && self.contentSize.height >= self.frame.size.height;
    BOOL isBouncingTop = self.contentOffset.y <= 0;

    BOOL isBouncing = isBouncingBottom || isBouncingTop;
    return isBouncing;
}

@end
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top