0

I have an array, collection view uses data from array while creating cells. Im adding some objects @ the beginning of the array, when my collectionview is almost at the top. I am using this method to determine if its time to load new items & sections and add them

-(void)collectionView:(UICollectionView *)collectionView willDisplayCell:(UICollectionViewCell *)cell forItemAtIndexPath:(NSIndexPath *)indexPath
{
    if(indexPath.section < sectionLimitBeforeLoadingMoreSections) 
    {
         // add some objects at the beginning of the array
    }
}

but i could easily use other methods (i.e. scrollViewDidScroll).

So i have a problem that when I add the items into array and reloadData, my collection view contentOffset doesnt get changed, so once this method is called, it gets called more and more and makes CPU work infinetely @ 100%.

Example: I have 20 sections, and initial position is center section(10). I start scrolling to top, and when i get to section 4, 10 more items are added to the array (that means 10 more sections are to appear). So section 4 must become section 14 now. So it does, but my scrollView contentOffset does not change, and new Section 4 is visible instantly, so it calles this method again to add 10 more items and so on.

When i use this method to add objects at the end of the array, it works fine. Sections get added at the bottom and I scroll fine.

I thought of a solution to determine height of all the new sections added, and add this value to the current contentOffset, but i dont see how can i calculate the height.


Update:

  if(indexPath.section < sectionLimitBeforeLoadingMoreSections) // load @ beginning
    {
        if(!self.isLoading)
        {
            self.isLoading = YES;
            CGFloat height = self.contentSize.height;
            [self performBatchUpdates:^
             {
                 [self loadNewMonthsAtTheBeginning:10];
                 [self insertSections:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, 10)]];
             }
                           completion:^(BOOL finished)
             {
                self.contentOffset = CGPointMake(self.contentOffset.x,self.contentOffset.y + self.contentSize.height - height);
                 self.isLoading = NO;
             }];
        }
    }

Seems to work well, but i get a little freeze when performing batch, any way to avoid that?

t0a0
  • 668
  • 1
  • 9
  • 18

1 Answers1

0

If you get a freeze then I would assume that loadNewMonthsAtTheBeginning is using too much processing time on main thread, you should consider performing the work done there in another thread.

If it is a web connection, consider using asynchronous calls such as mentioned here:how to send Asynchronous URL Request?

otherwise you could use GCD

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
    // Code run on non UI thread to perform tasks such as loadNewMonthsAtTheBeginning
    dispatch_async(dispatch_get_main_queue(), ^{
        // UI thread to perform insertSections
    });
});
Community
  • 1
  • 1
user3802077
  • 849
  • 9
  • 22
  • I tried dispatching, no success. Same method, which adds data to the end of the array(e.g. adding sections at the end of the collection view) works smoothly :( I guess it doesnt really freeze, but because i set content offset after i inserted new sections, it scrolls back to where it was and it looks like freeze. – t0a0 Oct 03 '14 at 20:51