Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Smooth Scrolling with 500+ images

SUPER EDIT:

Alright, after a few different revisions, I have a more clear question. Basically I'm struggling with using NSCache. I have a collection view as you can see below and I want to be able to minimize the scroll lag with the images, which I am doing for the most part. The difficult part is moving to the fullsize image. It's in another view and I would like the transition to the full-size photo as well as Apple does with their photos app.

It seems as though Apple is cache-ing the images and accessing them differently. I've found that I need to load the original thumbnail then when the fullsize image is downloaded I can replace it. But I'm not sure how to do this.

So far what I have is:

UICollectionview

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view.

    self.myCache = [[NSCache alloc] init];

}

//Reusable cell structure
- (UICollectionViewCell *)collectionView:(UICollectionView *)cv cellForItemAtIndexPath:(NSIndexPath *)indexPath {

    //cell
    CoverPhotoCell *cell = [cv dequeueReusableCellWithReuseIdentifier:@"CoverImgCell" forIndexPath:indexPath];
    cell.backgroundColor = [UIColor blackColor];
    cell.clipsToBounds = YES;
    cell.opaque = YES;
    cell.layer.shouldRasterize = YES;
    cell.layer.rasterizationScale = [UIScreen mainScreen].scale;

    Media *object = [[Media alloc] init];
    object = [self.photoListArray objectAtIndex:indexPath.item];

    //Remove old cell
    for (UIView *subview in [cell subviews]){
        if (subview.tag != 0 )
        {
            [subview removeFromSuperview];
        }
    }

    //UIImage
    UIImage *thumbImg = [_myCache objectForKey:object.url];

    if (thumbImg) {

        cell.imageView.image = thumbImg;
    }
    else {

        cell.imageView.image = nil;

        UIImage *thumbImg = [[UIImage alloc] initWithCGImage:[object.asset aspectRatioThumbnail]];

        dispatch_async(dispatch_get_main_queue(), ^{
            cell.imageView.image = thumbImg;
        });

        [_myCache setObject:thumbImg forKey:object.url];

    }

    //thumbnail
    cell.imageView.tag = indexPath.row + 1;

    cell.imageView.layer.borderWidth = 5;
    cell.imageView.layer.borderColor = [UIColor whiteColor].CGColor;
    cell.imageView.contentMode = UIViewContentModeScaleAspectFit;

    cell.imageView.frame = CGRectMake(0, 0, 125, 125);

    return cell;
}

//User taps image
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if ([segue.identifier isEqualToString:@"PhotoSegue"]) {
        DetailPageController *controller = segue.destinationViewController;

        NSIndexPath *selectedIndex = [self.collectionView indexPathsForSelectedItems][0];

        controller.initialIndex = (NSUInteger)selectedIndex.item;

        controller.photos = self.photoListArray;

    }
}

So that is my NSCache code, then I use a segue to the full view controller which displays the full resolution photo. How do I load the thumbnail first and then the full size image.

Also any thought on how apple loads its images so quickly? Are they using a different way to cache? Or am I doing something incorrectly.

Refined Edit:


Can someone post or at least point me toward some sample code where I show a thumbnail when the user scrolls fast and load the actual images when they slow down, similar to I guess apples movie trailers app.

like image 512
lostAstronaut Avatar asked Aug 30 '13 17:08

lostAstronaut


People also ask

How do I make Chrome scroll smoothly?

Type chrome://flags in the Chrome address bar. Scroll down to find the Smooth Scrolling setting. Change the setting from Default to Disabled. Restart Chrome.

How do I create a smooth scrolling anchor link?

You can use window. scroll() with behavior: smooth and top set to the anchor tag's offset top which ensures that the anchor tag will be at the top of the viewport.

What is Logitech smooth scrolling?

When this feature is enabled, pressing the Page Down button won't just jump directly down one page. With smooth scrolling, it slides down smoothly, so you can see how much it scrolls. This might not be a huge deal for you but it is a big deal for users who read a lot of long pages.


1 Answers

A complete answer with code would be too much for SO. So I try to describe the basics:

You should create your own image cache. With a page scroll view, there are at max two images visible. Viewing photos in a paging enabled scroll view, the image cache must at least hold three images of full size.

The cache works as follows:

Assuming you have a list of images, which can be accessed by an index which corresponds to the position within the scroll view of the "Album Viewer".

From the current index, (asynchronously) load images into the cache for index-1, index and index+1, unless this image exists already in cache or the index is out of range.

When the user begins scrolling the next image will become visible.

When the user scrolls forward and has scrolled half one page, the current index will increase by one. At this point, two images are visible - each half of it. Now, when the index changes, you throw the image at current index-2 and load the next image at current index + 1.

When the user scrolls backward, the index will decrease by one. You throw the at index+2 and load the corresponding image for current index-1.

You can improve that scheme by adding a thumb view cache which works exactly like the above, but uses a wider range, say loading 20 images in advance. Use the thumb images as "placeholders" when the full sized image is not yet loaded (note: everything shall be asynchronous).

If the user scrolls "fast", don't load the full sized images, just wait until the velocity decreasing to certain amount. You can determine the velocity of scrolling with some effort.

If the user scrolls really fast, then even the thumb image is not available when it should be displayed. Then, resort to a static placeholder image. (Also take care not to override a full sized image with a thumb image).

like image 167
CouchDeveloper Avatar answered Sep 21 '22 21:09

CouchDeveloper