如何测试滚动视图是否弹跳?

时间:2010-05-18 00:44:55

标签: iphone uiscrollview uiscrollviewdelegate

如何测试滚动视图是否弹跳?反弹结束时是否有通知或其他内容?

7 个答案:

答案 0 :(得分:31)

以下是我如何检测滚动视图是否水平弹跳:

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

答案 1 :(得分:22)

我已经为UIScrollView实现了扩展,以便对垂直和水平滚动进行处理。即使对于非零的contentInsets,以及当内容不足以覆盖scrollView插件时,这也会起作用:

<强>目标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
  }
}

对于 RxSwift ,您只需将scrollViewDidScroll映射到isBouncing,然后使用distinctUntilChanged进行过滤。

答案 2 :(得分:9)

Justin方法的一个小修正,允许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" );
}

答案 3 :(得分:7)

是的...查看UIScrollViewDelegate规范,实现包括下面两个方法的方法,并相应地设置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;

您可能对scrollViewDidEndDecelerating最感兴趣。这些也可以在我最初找到它们的UITableView中工作(UITableView继承自UIScrollView)。

答案 4 :(得分:1)

对于那些能够在滚动视图中向下“反弹”以更新视图内容的人。 (事件只被解雇一次。)

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

答案 5 :(得分:1)

旧问题,但我刚遇到类似的问题,并想补充一点,最好还检查滚动视图内容是否大于滚动视图的框架:

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

现在确保滚动视图足够大以处于滚动弹跳状态,因此如果滚动视图很小,它并不总是评估为真。

干杯

答案 6 :(得分:0)

使用Glavid的答案,我还添加了弹跳到底部,并添加为类别

#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