Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can IOS Photos app can show hundreds of photos in one screen?

I am working on an application that relies on showing lots of photos on screen from multiple sources.

I am wondering how could apple make that "photo tile" view in their photo app? With that much photos, in my opinion the app should give memory warning with less photos (even if i load photos in "thumbnail size") displayed at once, but i can see that it can show hundreds of photos in one screen when i zoom out.

One way i can think of is these views are not individual photos but they are single 'tiled' images generated from photos on real time, so the app just shows 2-3 photos at once. But this still needs lots of cpu power and time to generate that fast. I can zoom in or out instantly .

I want to achieve similar functionality in my app, any directions on how to achieve this would be great.

Thanks for answers.

IOS 7 Photos.app

like image 364
dreampowder Avatar asked Oct 10 '14 10:10

dreampowder


1 Answers

I have made some research and found that IOS8 has a wonderful new framework called "Photos Framework"

This Framework lets you easily cache images, call thumbnail images with predefined sizes and load items. (old ALAsset library just had one "thumbnail" size, you had to resize your own.)

on my test a screen full of 20x20 photos (my phones screen content 384 images), app only takes 10mb's of memory, and almost no flickering when scrolling. Smooth scrolling can be achieved by optimizing cell reloading imo.

Heres the code i've used for loading images into a uicollectionview with 20x20 item size:

@import Photos;
@interface MainViewController ()

@property (strong) PHFetchResult *assetsFetchResults;
@property (strong) PHCachingImageManager* imageManager;

@end

on viewDidLoad:

- (void)viewDidLoad {
    [super viewDidLoad];

    self.imageManager = [[PHCachingImageManager alloc] init];

    CGFloat scale = [UIScreen mainScreen].scale;
    CGSize cellSize = ((UICollectionViewFlowLayout *)self.collectionViewLayout).itemSize;
    AssetGridThumbnailSize = CGSizeMake(cellSize.width * scale, cellSize.height * scale);

    [self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:reuseIdentifier];
    self.assetsFetchResults = [PHAsset fetchAssetsWithOptions:nil];
    // Do any additional setup after loading the view.
}

and collection view datasource methods:

#pragma mark <UICollectionViewDataSource>

- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
    return 1;
}


- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
    return self.assetsFetchResults.count;
}

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
    UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:reuseIdentifier forIndexPath:indexPath];

    [self.imageManager requestImageForAsset:self.assetsFetchResults[indexPath.item] 
                                 targetSize:CGSizeMake(20, 20) 
                                contentMode:PHImageContentModeAspectFill 
                                    options:nil resultHandler:^(UIImage *result, NSDictionary* info){

                                        UIImageView* imgView = (UIImageView*)[cell.contentView viewWithTag:999];
                                        if(!imgView) {
                                            imgView = [[UIImageView alloc] initWithFrame:[cell.contentView bounds]];
                                            imgView.tag = 999;
                                            [cell.contentView addSubview:imgView];
                                        }
                                        imgView.image = result;
                                    }];
    // Configure the cell

    return cell;
}

Thats it!

like image 182
dreampowder Avatar answered Sep 25 '22 06:09

dreampowder