为什么当我向同一方向快速滑动两次时,UIScrollView 会剧烈滚动?

发布于 2024-11-27 03:11:41 字数 1618 浏览 2 评论 0原文

在 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 没有做任何特殊操作,在滚动视图上设置的唯一属性是

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

:从托管 uiscrollview 的 uiviewcontroller 中的 viewwillappear 调用添加一次(并且 contentSize 已适当设置)。滚动,等待一会儿,然后再次滚动,效果非常好。

when scrolling horizontally in a UIScrollview, if I quickly swipe twice in the same direction the scroll view jumps violently. Is there anyway to prevent this from happening? To explain in detail, here's an event log from the scrollview where in most delegate methods I just print the x coordinate.

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

The most notable thing in the log is right after scrollViewWillBeginDeceleration when the contentoffset.x jumps with ~6000 points in a matter of milliseconds.

Implementation

The uiscrollview and uiscrollviewdelegate are in the same class, a subclass of uiscrollview which also implements the uiscrollviewdelegate protocol, nothing special is done to contentoffset, and the only properties set on the scrollview are:

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

The scrollview subviews are added once from a viewwillappear call in a uiviewcontroller which hosts the uiscrollview (and the contentSize is set appropriately). Scrolling, waiting a little while, and scrolling again works perfectly.

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

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

发布评论

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

评论(4

当爱已成负担 2024-12-04 03:11:42

将滚动视图设置为您所需的方向以及您想要滚动的坐标并使用与 XIB 的正确连接,这样它就能正常工作。

Please set the scroll view in your required direction and as well as co-ordinate for which you want the scroll and use the proper connection to XIB then it will work fine.

旧时光的容颜 2024-12-04 03:11:42

你可以这样尝试

- (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];
}

you can try it like this

- (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];
}
爱人如己 2024-12-04 03:11:42

您可能需要设置 bouncesZoom 属性?

scrollviewobject.bouncesZoom = NO;

May be you need to setup the bouncesZoom property?

scrollviewobject.bouncesZoom = NO;
零度℉ 2024-12-04 03:11:42

如果您希望 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; }

If you want the UIScrollView to scroll a bit slower you could for example add a NSTimer when user scroll's and set the scrollers contentOffset a bit back with an animation like so:

Declare in .h File:

UIScrollView *myScrollView;
NSTimer *scrollCheckTimer;
BOOL delayScroll;

.m File:

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