I've checked through few solutions to the problem of infinite scrolling in UICollectionView
, but none of them works perfectly (1, 2, 3 and even tutorial - 4).
Main problem is with the fact, that UICollectionView
contains images. When i scroll to first or last item (to make it infinite), before they load i can see a very short 'blink' that has to be removed. I don't know how to fix it, any help will be kindly welcomed.
I should mention, that the gallery i'm making shouldn't allow for any user interaction, it should scroll by itself (a presentation lets say).
Two most interesting approaches I've tried:
Method 1: 14 items in collectionView, in such order: @[8, 9, @[0-9], 0, 1] (so 8,9,1,2 are duplicated)
// a timer to move everything
_timer = [NSTimer scheduledTimerWithTimeInterval:0.02f target:self selector:@selector(scroll) userInfo:nil repeats:YES];
// timer selector
- (void)scroll {
self.collectionView.contentOffset = CGPointMake(self.collectionView.contentOffset.x+1, self.collectionView.contentOffset.y);
}
// check if we need to change offset
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"something" forIndexPath:indexPath];
if ([self scrollProperly]) {
// return cell;
}
}
// method to check & set proper offset (author: D33pN16h7)
- (BOOL)scrollProperly {
// check if near the end or beginning
BOOL test = NO;
CGFloat currentOffsetX = self.collectionView.contentOffset.x;
CGFloat currentOffSetY = self.collectionView.contentOffset.y;
CGFloat contentWidth = self.collectionView.contentSize.width;
if (currentOffsetX < (contentWidth / 6.0f)) {
self.collectionView.contentOffset = CGPointMake((currentOffsetX + (contentWidth/2)), currentOffSetY);
test = YES;
}
if (currentOffsetX > ((contentWidth * 4)/ 6.0f)) {
self.collectionView.contentOffset = CGPointMake((currentOffsetX - (contentWidth/2)), currentOffSetY);
test = YES;
}
return test;
}
Second approach: 20 items in collectionView, in such order: @[@[0-9], @[0-9]] (so whole array is duplicated). There is also timer, same is in previous method. Instead of running [self scrollProperly]
in collectionView:cellForItemAtIndexPath:
here we use:
if (indexPath.row == 2) {
[collectionView scrollToItemAtIndexPath:[NSIndexPath indexPathForRow:([collectionView numberOfItemsInSection:indexPath.section] - 3) inSection:indexPath.section] atScrollPosition:UICollectionViewScrollPositionNone animated:NO];
} else if (indexPath.row == ([collectionView numberOfItemsInSection:indexPath.section] - 1)) {
[collectionView scrollToItemAtIndexPath:[NSIndexPath indexPathForRow:2 inSection:indexPath.section] atScrollPosition:UICollectionViewScrollPositionNone animated:NO];
}