I\'m attempting to setup a scrollview with infinite (horizontal) scrolling.
Scrolling forward is easy - I have implemented scrollViewDidScroll, and when the contentO
I found a really great example app by Apple to implement Infinite Scrolling using a similar idea in the OP. Very simple and most importantly no tearing.
http://developer.apple.com/library/ios/#samplecode/StreetScroller/Introduction/Intro.html
They implemented the "content recentering" every time layoutSubviews
was called on the UIScrollView.
The only adjustment I made was to recycle the "tiling effect" instead of throwing away old tiles and allocing new ones.
You can see this example
numbercolors=[[NSMutableArray alloc] init];
//total count of array is 49
numbercolors = [NSMutableArray arrayWithObjects:@"25",@"26",@"27",@"28",@"29",@"31",@"32",@"33",@"34",@"35","0",@"1",@"2",@"3",@"4",@"5",@"6",@"7",@"8",@"9",@"10",@"11",@"12",@"13",@"14",@"15",@"16",@"17",@"18",@"19",@"20",@"21",@"22",@"23",@"24",@"25",@"26",@"27",@"28",@"29",@"30",@"31",@"32",@"33",@"34",@"35", @"0",@"1",@"2",@"3",nil];
int x=2500;
for (NSInteger index = 0; index < [numbercolors count]; index++)
{
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
button.frame = CGRectMake(x ,0,29.0,77.0);
button.tag = index;
[button setTitle:[numbercolors objectAtIndex:index] forState:UIControlStateNormal];
[button addTarget:self action:@selector(didTapButton:)
forControlEvents:UIControlEventTouchUpInside];
[coloringScroll addSubview:button];
x=x+70+29;
}
[coloringScroll setContentSize:CGSizeMake(5000+ (29+70)*[numbercolors count], 1)];
[coloringScroll setContentOffset:CGPointMake(2500+(29+70)*11, 0)];
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
if (scrollView.contentOffset.x > 2500+(29+70)*4 + ((29+70)*36))
{
[scrollView setContentOffset:CGPointMake(scrollView.contentOffset.x-((29+70)*36), 0)];
}
if (scrollView.contentOffset.x < 2500+(29+70)*4)
{
[scrollView setContentOffset:CGPointMake(scrollView.contentOffset.x+((29+70)*36),
0)];
}
}
(hope I'm posting this correctly - I'm new here!?)
mvds was spot on - thanks - subclassing UIScrollView works perfectly - I'm yet to implement the shifting and loading of new data, but I have a UIScrollView that scrolls round in an endless loop!
Heres the code:
#import "BRScrollView.h"
@implementation BRScrollView
- (id)awakeFromNib:(NSCoder *)decoder {
offsetAdjustment = 0;
[super initWithCoder:decoder];
return self;
}
- (void)setContentOffset:(CGPoint)contentOffset {
float realOffset = contentOffset.x + offsetAdjustment;
//This happens when contentOffset has updated correctly - there is no need for the adjustment any more
if (realOffset < expectedContentOffset-2000 || realOffset > expectedContentOffset+2000) {
offsetAdjustment = 0;
realOffset = contentOffset.x;
}
float pageNumber = realOffset / 320;
float pageCount = self.contentSize.width / 320;
if (pageNumber > pageCount-4) {
offsetAdjustment -= 3200;
realOffset -= 3200;
}
if (pageNumber < 4) {
offsetAdjustment += 3200;
realOffset += 3200;
}
//Save expected offset for next call, and pass the real offset on
expectedContentOffset = realOffset;
[super setContentOffset:CGPointMake(realOffset, 0)];
}
- (void)dealloc {
[super dealloc];
}
@end
Notes:
If you actually want an infinite loop, you'd need to adjust the numbers - this codes notices when you get near the edge and moves you to just beyond the middle
My contentSize is 6720 (21 pages)
I'm only interest in scrolling horizontally, so only save the x values and hard code the y to 0!
Ben
Have a look at this too (the video will give you a quick idea of what it does): http://dev.doukasd.com/2011/04/infinite-scrolling-dial-control-for-ios/
It's not horizontal but it should be useful. I tried what you were suggesting, but setting the content offset never looked right while the scroll view was animating, the animation would always break up.