【问题标题】:Why does UIScrollView scroll violently when I quickly swipe twice in the same direction?为什么我向同一个方向快速滑动两次时,UIScrollView 会剧烈滚动?
【发布时间】:2011-10-15 23:11:54
【问题描述】:

在 UIScrollview 中水平滚动时,如果我在同一方向快速滑动两次,滚动视图会剧烈跳跃。有没有办法防止这种情况发生?为了详细解释,这里有一个来自滚动视图的事件日志,在大多数委托方法中,我只打印 x 坐标。

scrollViewWillBeginDragging:
    14:55:12.034 Will begin dragging!
    14:55:12.037 - Position -0.000000
scrollViewWillBeginDeceleration:
    14:55:12.129 Deceleration rate 0.998000
    14:55:12.152 + Position 314.000000
scrollViewWillBeginDragging:
    14:55:12.500 Will begin dragging!
    14:55:12.522 - Position 1211.000000
scrollViewWillBeginDeceleration:
    14:55:12.530 Deceleration rate 0.998000
    14:55:12.533 + Position 1389.000000
scrollViewDidScroll: (printing values < 0 && > 6000 (bounds.size.width)
    14:55:12.595 !!! Position 7819.000000
    14:55:12.628 !!! Position 9643.000000
    14:55:12.658 !!! Position 10213.000000
    14:55:12.688 !!! Position 10121.000000
    14:55:12.716 !!! Position 9930.000000
    ... contentoffset.x drops with around 400 each scrollviewdidscroll call ...
    14:55:13.049 !!! Position 6508.000000
scrollViewDidEndDecelerating:
    14:55:13.753 Will end deceleration
    14:55:13.761 * Position 6144.000000

日志中最值得注意的是在 scrollViewWillBeginDeceleration 之后 contentoffset.x 在几毫秒内以约 6000 点跳跃。

实施

uiscrollview 和 uiscrollviewdelegate 属于同一个类,是 uiscrollview 的子类,也实现了 uiscrollviewdelegate 协议,contentoffset 没有什么特别的,只在scrollview 上设置的属性有:

    self.showsHorizontalScrollIndicator = YES;
    self.scrollsToTop = NO;
    self.delegate = self;

滚动视图子视图是通过在承载 uiscrollview 的 uiviewcontroller 中的 viewwillappear 调用添加一次(并且 contentSize 已适当设置)。滚动,稍等片刻,然后再次滚动完美。

【问题讨论】:

  • 似乎根本原因是背景颜色与 [UIColor colorWithPattern:...] 在绘制时产生了轻微的延迟,滚动视图中的子视图都没有被移动或绘制,但是 contentOffset.x还是增加了。当滚动视图终于开始移动时,contentOffset.x 急剧增加,甚至远远超出了内容的范围,导致视图以一种可怕的方式跳转到该偏移量。通过使用较轻(或无背景),我能够获得更流畅的滚动。
  • 如果您将背景放在滚动视图后面的另一个视图中并将滚动视图的背景颜色设置为透明怎么办?
  • 您是否使用任何自定义加速度方程直接更新滚动视图的偏移值来执行滚动动画?

标签: objective-c ios uiscrollview uiscrollviewdelegate


【解决方案1】:

您可能需要设置bouncesZoom 属性吗?

scrollviewobject.bouncesZoom = NO;

【讨论】:

    【解决方案2】:

    你可以这样试试

    - (void)enableScrollView
    {
        scrollView.userInteractionEnabled = YES;
    }
    
    - (void)delayScroll:(id)sender
    {
        NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
        //delay userInteraction 0.1 second, prevent second swipe
        [NSThread sleepForTimeInterval:0.1];
        [self performSelectorOnMainThread:@selector(enableScrollView) withObject:nil waitUntilDone:NO];
        [pool release];
    }
    
    - (void)scrollViewDidScroll:(UIScrollView *)scrollView
    {
        scrollView.userInteractionEnabled = NO;
        [NSThread detachNewThreadSelector:@selector(delayScroll:) toTarget:self withObject:nil];
    }
    

    【讨论】:

      【解决方案3】:

      如果您希望 UIScrollView 滚动得慢一点,例如,您可以在用户滚动时添加一个 NSTimer,并使用如下动画将滚动条 contentOffset 设置得稍微靠后一点:

      在 .h 文件中声明:

      UIScrollView *myScrollView;
      NSTimer *scrollCheckTimer;
      BOOL delayScroll;
      

      .m 文件:

      - (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate {
          if (delayScroll == YES) {
              [scrollCheckTimer invalidate];
              delayScroll = NO;
              [myScrollView setContentOffset:CGPointMake(myScrollView.contentOffset.x - 40, contentOffset.y) animated:YES];
          }
          delayScroll = YES;
          scrollCheckTimer = [NSTimer scheduledTimerWithTimeInterval:0.9 target:self selector:@selector(removeDelayBecouseOfTime) userInfo:nil repeats:NO];
      }
      
      - (void)removeDelayBecouseOfTime { delayScroll = NO; }
      

      【讨论】:

        【解决方案4】:

        将滚动视图设置在您需要的方向以及您想要滚动的坐标并使用与XIB的正确连接,然后它将起作用很好。

        【讨论】:

          猜你喜欢
          • 2012-06-15
          • 2019-02-15
          • 2011-07-19
          • 1970-01-01
          • 2014-08-26
          • 1970-01-01
          • 1970-01-01
          • 2012-07-01
          • 1970-01-01
          相关资源
          最近更新 更多