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

发布于 2024-09-01 17:53:00 字数 33 浏览 12 评论 0原文

如何测试滚动视图是否弹跳?弹跳结束时有通知什么的吗?

How can I test if the scroll view is bouncing? Is there a notification or something when the bounce ends?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

瞎闹 2024-09-08 17:53:00

以下是我检测滚动视图是否水平弹动的方法:

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

Here is how I detected if the scroll view is bouncing horizontally:

- (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");
  }
}
乱世争霸 2024-09-08 17:53:00

我已经实现了 UIScrollView 的扩展来处理垂直和水平滚动。即使 contentInsets 不为零,并且内容不够大,无法覆盖滚动视图插入,这也适用:

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

For RxSwiftscrollViewDidScroll 映射到 isBouncing 并使用 distinctUntilChanged 进行过滤即可。

I've implemented extension for UIScrollView to handle this for vertical and horizontal scrolling. This will work even with non-zero contentInsets and in case when content is not big enough for covering scrollView insets:

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

For RxSwift you can just map scrollViewDidScroll with isBouncing and filter with distinctUntilChanged.

篱下浅笙歌 2024-09-08 17:53:00

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

A minor amendment to Justin's method, allowing for 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" );
}
眼泪也成诗 2024-09-08 17:53:00

是的...查看 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)。

Yes... check out the UIScrollViewDelegate spec, implement the methods including the two below, and set your UIScrollView's delegate accordingly:

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

You will probably be most interested in scrollViewDidEndDecelerating. These also work in UITableView which is where I originally found them (UITableView inherits from UIScrollView).

岁月流歌 2024-09-08 17:53:00

老问题,但我刚刚遇到了类似的问题,想补充一点,检查滚动视图内容是否大于滚动视图的框架是一个好主意:

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

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

干杯

Old question but I just ran into a similar issue and wanted to add that it is a good idea to also check that the scroll views content is larger than the scroll view's frame:

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

This now makes sure the scroll view is large enough to be in a scroll-bouncing state, so that if the scroll view is small it does NOT always evaluate to true.

Cheers

何其悲哀 2024-09-08 17:53:00

对于那些能够在滚动视图中向下“弹跳”以更新视图内容的人。 (并且该事件仅触发一次。)

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

For those of you who would be able to "bounce" downwards in a scrollview in order to update contents of the view. (And the event is only fired once.)

- (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");
    }
}
好倦 2024-09-08 17:53:00

使用 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

Using Glavid's answer, I added bouncing to bottom also, and added as a category

#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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文