Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NSCollectionView lazy-loading like behavior

I am trying to get lazy-loading like behavior from my NSCollectionView. (honestly I assumed it had it, like a UITableView - seems like an obvious omission?)

Anyway, I am displaying images in the cells, and would like to load images as they are about to scroll into view, and unload them after they leave.

This is for a research tool and does not need to be pretty - ie: stuff can "pop" in.

Any ideas? My first thought is to find some way for the Views in the collection to know when they're onscreen, but drawrect seems to be called many many times, far more times than there are views on screen.

like image 400
user441669 Avatar asked Jul 24 '14 23:07

user441669


1 Answers

As you mention, NScollectionView builds all cells at once. Specially if there are lots of images inside cells that cause performance issues. This is how I solve the problem. There might be a better solutions but as far as this is working fine for me. For a long time I have observed performance of the code with Instruments and did not see any down side.

- (void)windowDidLoad {
    //Here adding observer to NSCollectionView's scrollview to monitor bounds changes.
    NSView *contentView = [scrollViewOfYourCollectionView contentView];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(boundDidChange:) name:NSViewBoundsDidChangeNotification object:contentView];
}

- (void)boundDidChange:(NSNotification *)notification
{
    NSRect collectionViewVisibleRect = yourCollectionView.visibleRect;
    //collectionViewVisibleRect.size.height += 300; //If you want some preloading for lower cells...

    for (int i = 0; i < yourDataSourceArray.count; i++) {
         NSCollectionItem *item = [yourCollectionView itemAtIndex:i];
         if (NSPointInRect(NSMakePoint(item.view.frame.origin.x, item.view.frame.origin.y), collectionViewVisibleRect) == YES)
         {
             if (item.imageView.image == nil) {
                 dispatch_async(dispatch_get_main_queue(), ^{
                 //Fill your cells. 
                 //to showing/downloading images I am using SDWebImage. 
                 });
             }
         }
    }
}
like image 158
modus Avatar answered Nov 10 '22 16:11

modus