使用scrollViewWillEndDragging确保UIScrollView以定义的增量停止

时间:2015-07-23 19:08:23

标签: ios objective-c uiscrollview uiscrollviewdelegate

我希望我的UIScrollView以某些增量值自然地滑行到结尾,对应于水平滚动UIScrollView的每50个宽度点。为此,我定制了scrollViewWillEndDragging,就像这样(按照建议,但在Scrolling a horizontal UIScrollView in stepped increments?)答案中没有详细描述:

- (void) scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset{

    if(fmodf(targetContentOffset->x, 50.0)){
        int roundingNumber1 = 50;
        CGFloat newOffset = roundingNumber1 * floor(((scrollView.contentOffset.x)/roundingNumber1)+0.5);
        targetContentOffset->x = newOffset;
    }

}

但是,我不确定这实际上是以特定的增量停止视图,我也注意到效果是不对称的。 虽然我的滚动动作/速度/等是相同的,但向右滚动比向左滚动要流畅得多。向右滚动停止更快,更突然。有视频here。为什么这种行为不对称,我该如何改变呢?

我瘦的滚动不是以50为增量停止的原因是我在滚动视图下面还有一个UILabel,它被其他委托函数更新以显示偏移量。 滚动完成后,它显示的值很少接近50。这是因为滚动没有递增到50或因为我没有在正确的时间更新吗?

感谢您的任何建议。

- (void) scrollViewDidScroll:(UIScrollView *)scrollView{

    if(abs(self.lastOffset - scrollView.contentOffset.x) > 49){
        CGFloat newNumber = scrollView.contentOffset.x;
        self.numberProperty.text = [NSString stringWithFormat:@"%.00f", scrollView.contentOffset.x];
        self.lastOffset = scrollView.contentOffset.x;
        [self.view setNeedsDisplay];
    }
}

- (void) scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView{
            self.numberProperty.text = [NSString stringWithFormat:@"%.00f", scrollView.contentOffset.x];
}

1 个答案:

答案 0 :(得分:2)

您可以将滚动视图上的pagingEnabled设置为true,而不是实现这些委托方法,以免费获得此行为。启用分页后,滚动视图将自动捕捉到最近的"页面"当您结束拖动时,页面宽度等于滚动视图的宽度。

根据您的视频,滚动视图中的项目似乎小于滚动视图本身的宽度。要使用分页,您必须执行以下操作:

  1. 使滚动视图的宽度与您的某个项目相同(在您的情况下为50.0单位)。
  2. scrollView.clipsToBounds设置为false,以便滚动视图在其小得多的范围之外绘制子视图。
  3. scrollView.pagingEnabled设置为true,以便滚动视图以分页方式滚动。
  4. 此时,分页将起作用,但您无法将滚动视图拖动到其边界之外。要使其工作,您需要将滚动视图嵌入到更大的视图中,以便将触摸事件转发给它。

    1. 创建"触摸转发"将它添加到您的视图中。
    2. 此类接收它收到的所有触摸事件,并将它们发送到targetView属性。 DJK是我为课程名称编写的随机前缀。

      @interface DJKTouchForwardingView : UIView
      
      /** The view to which touch events should be forwarded. */
      @property (weak, nonatomic) UIView *targetView;
      
      @end
      
      @implementation DJKTouchForwardingView
      
      - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
      {
          UIView *child = nil;
          if ((child = [super hitTest:point withEvent:event]) == self) {
              return self.targetView;
          }
          return child;
      }
      
      @end
      
      1. 使滚动视图成为触摸转发视图的子视图,并将其分配给targetView属性。
      2. 您的滚动视图现在可以在触摸转发视图的范围内滚动,并将捕捉到50个单位页面。