16 votes

Comment puis-je tester si la vue défilante rebondit ?

Comment puis-je tester si la vue défilante rebondit ? Y a-t-il une notification ou autre chose lorsque le rebond se termine ?

34voto

Justin Tanner Points 5437

Voici comment j'ai détecté si la vue de défilement rebondit horizontalement :

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

28voto

Timur Bernikowich Points 328

J'ai implémenté une extension pour UIScrollView afin de gérer le défilement vertical et horizontal. Cela fonctionnera même avec des contentInsets non nuls et dans le cas où le contenu n'est pas assez grand pour couvrir les insets du scrollView :

Objectif-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 et plus

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

Pour RxSwift vous pouvez simplement mettre en correspondance scrollViewDidScroll avec isBouncing et filtrer avec distinctUntilChanged .

9voto

Henry Cooke Points 989

Une modification mineure à la méthode de Justin, permettant le contentInset :

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

7voto

Adam Eberbach Points 9587

Oui... consultez la spécification UIScrollViewDelegate, implémentez les méthodes, y compris les deux ci-dessous, et définissez le délégué de votre UIScrollView en conséquence :

// 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;

Vous serez probablement plus intéressé par la fonction scrollViewDidEndDecelerating. Elles fonctionnent également dans UITableView, où je les ai trouvées à l'origine (UITableView hérite de UIScrollView).

3voto

Glavid Points 56

Vieille question mais je viens de rencontrer un problème similaire et je voulais ajouter que c'est une bonne idée de vérifier également que le contenu de la vue défilante est plus grand que le cadre de la vue défilante :

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

Cela permet maintenant de s'assurer que la vue défilante est suffisamment grande pour être dans un état de rebondissement de défilement, de sorte que si la vue défilante est petite, cela n'évalue PAS toujours à true.

Cheers

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X