UIScrollView 无限滚动

时间:2022-10-16
本文介绍了UIScrollView 无限滚动的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

问题描述

我正在尝试设置一个无限(水平)滚动的滚动视图.

I'm attempting to setup a scrollview with infinite (horizontal) scrolling.

向前滚动很容易——我已经实现了 scrollViewDidScroll,当 contentOffset 接近尾声时,我将滚动视图的 contentsize 放大并在空间中添加更多数据(我将不得不处理稍后会产生的严重影响!)

Scrolling forward is easy - I have implemented scrollViewDidScroll, and when the contentOffset gets near the end I make the scrollview contentsize bigger and add more data into the space (i'll have to deal with the crippling effect this will have later!)

我的问题是向后滚动 - 计划是看看我何时接近滚动视图的开头,然后当我确实使 contentsize 更大时,移动现有内容,将新数据添加到开头,然后 -重要的是调整 contentOffset 使视口下的数据保持不变.

My problem is scrolling back - the plan is to see when I get near the beginning of the scroll view, then when I do make the contentsize bigger, move the existing content along, add the new data to the beginning and then - importantly adjust the contentOffset so the data under the view port stays the same.

如果我慢慢滚动(或启用分页),这非常有效,但如果我走得快(甚至不是很快!)它会发疯!代码如下:

This works perfectly if I scroll slowly (or enable paging) but if I go fast (not even very fast!) it goes mad! Heres the code:

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

    float pageNumber = scrollView.contentOffset.x / 320;
    float pageCount = scrollView.contentSize.width / 320;

    if (pageNumber > pageCount-4) {
        //Add 10 new pages to end
        mainScrollView.contentSize = CGSizeMake(mainScrollView.contentSize.width + 3200, mainScrollView.contentSize.height);
        //add new data here at (320*pageCount, 0);
    }

    //*** the problem is here - I use updatingScrollingContent to make sure its only called once (for accurate testing!)
    if (pageNumber < 4 && !updatingScrollingContent) {

        updatingScrollingContent = YES;

        mainScrollView.contentSize = CGSizeMake(mainScrollView.contentSize.width + 3200, mainScrollView.contentSize.height);
        mainScrollView.contentOffset = CGPointMake(mainScrollView.contentOffset.x + 3200, 0);
        for (UIView *view in [mainContainerView subviews]) {
            view.frame = CGRectMake(view.frame.origin.x+3200, view.frame.origin.y, view.frame.size.width, view.frame.size.height);
        }
        //add new data here at (0, 0);      
    }

    //** MY CHECK!
    NSLog(@"%f", mainScrollView.contentOffset.x);
}

随着滚动的发生,日志显示:1286.5000001285.5000001284.5000001283.5000001282.5000001281.5000001280.500000

As the scrolling happens the log reads: 1286.500000 1285.500000 1284.500000 1283.500000 1282.500000 1281.500000 1280.500000

然后,当 pageNumber<4 时(我们即将开始):4479.5000004479.500000

Then, when pageNumber<4 (we're getting near the beginning): 4479.500000 4479.500000

太棒了!- 但数字应该会在 4,000 秒内继续下降,但下一个日志条目显示:1278.0000001277.0000001276.5000001275.500000等等……

Great! - but the numbers should continue to go down in the 4,000s but the next log entries read: 1278.000000 1277.000000 1276.500000 1275.500000 etc....

从中断的地方继续!

仅作记录,如果滚动缓慢,日志会显示:1294.5000001290.0000001284.5000001280.5000004476.0000004476.0000004473.0000004470.0000004467.5000004464.0000004460.5000004457.500000等等……

Just for the record, if scrolled slowly the log reads: 1294.500000 1290.000000 1284.500000 1280.500000 4476.000000 4476.000000 4473.000000 4470.000000 4467.500000 4464.000000 4460.500000 4457.500000 etc....

有什么想法吗????

谢谢

本.

推荐答案

可能是无论在其中设置这些数字,都不会因为您将 contentOffset 设置在其手中而留下深刻印象.所以它只是继续设置它认为应该是下一个瞬间的 contentOffset - 而不验证 contentOffset 在此期间是否发生了变化.

It could be that whatever is setting those numbers in there, is not greatly impressed by you setting the contentOffset under its hands. So it just goes on setting what it thinks should be the contentOffset for the next instant - without verifying if the contentOffset has changed in the meantime.

我会将 UIScrollView 子类化并将魔法放在 setContentOffset 方法中.根据我的经验,所有内容偏移更改都通过该方法,即使是内部滚动引起的内容偏移更改.只需在某个时候执行 [super setContentOffset:..] 即可将消息传递给真正的 UIScrollView.

I would subclass UIScrollView and put the magic in the setContentOffset method. In my experience all content-offset changing passes through that method, even the content-offset changing induced by the internal scrolling. Just do [super setContentOffset:..] at some point to pass the message on to the real UIScrollView.

也许如果你把你的换档动作放在那里它会更好.您至少可以检测到 contentOffset 的 3000-off 设置,并在传递消息之前对其进行修复.如果您还要覆盖 contentOffset 方法,您可以尝试看看是否可以制作一个虚拟的无限内容大小,然后在后台"将其缩小到真实比例.

Maybe if you put your shifting action in there it will work better. You could at least detect the 3000-off setting of contentOffset, and fix it before passing the message on. If you would also override the contentOffset method, you could try and see if you can make a virtual infinite content size, and reduce that to real proportions "under the hood".

这篇关于UIScrollView 无限滚动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

上一条:如何以编程方式强制停止 UIScrollView 中的滚动? 下一条:带有自动布局的 UIScrollView 内的 UITextView

相关文章

最新文章