I’m attempting to setup a scrollview with infinite (horizontal) scrolling.
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!)
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);
}
As the scrolling happens the log reads:
1286.500000
1285.500000
1284.500000
1283.500000
1282.500000
1281.500000
1280.500000
Then, when pageNumber<4 (we’re getting near the beginning):
4479.500000
4479.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….
Continiuing from where it left off!
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….
Any ideas????
Thanks
Ben.
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.
I would subclass UIScrollView and put the magic in the
setContentOffsetmethod. 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.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
contentOffsetmethod, you could try and see if you can make a virtual infinite content size, and reduce that to real proportions “under the hood”.