Comment puis-je tester si la vue défilante rebondit ? Y a-t-il une notification ou autre chose lorsque le rebond se termine ?
Réponses
Trop de publicités?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");
}
}
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
.
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" );
}
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).
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
- Réponses précédentes
- Plus de réponses