【问题标题】:How can I test if the scroll view is bouncing?如何测试滚动视图是否在弹跳?
【发布时间】:2011-02-20 16:32:12
【问题描述】:

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

【问题讨论】:

    标签: iphone uiscrollview uiscrollviewdelegate


    【解决方案1】:

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

    【讨论】:

    • 非常感谢。我知道这种方式,我只是认为还有另一种方法。谢谢! :)
    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        【解决方案4】:

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

        - (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】:

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

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

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

          干杯

          【讨论】:

            【解决方案6】:

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

            【讨论】:

              【解决方案7】:

              我已经为 UIScrollView 实现了扩展来处理垂直和水平滚动。这甚至适用于非零 contentInsets 并且在内容不足以覆盖 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
                }
              }
              

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

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2017-01-11
                • 1970-01-01
                • 2019-03-17
                • 1970-01-01
                • 2013-09-01
                相关资源
                最近更新 更多