How to use PHCachingImageManager

前端 未结 1 1032
深忆病人
深忆病人 2020-12-09 23:08

I know that there is already this question on SO, but I don\'t think that the given answer is satisfying/complete: How can IOS Photos app can show hundreds of photos in one

相关标签:
1条回答
  • 2020-12-09 23:37

    Refer this Photos Framework example In this project you should look into the file AAPLAssetGridViewController.m and how it handles caching based on your scroll position.

     - (void)updateCachedAssets
            {
                BOOL isViewVisible = [self isViewLoaded] && [[self view] window] != nil;
                if (!isViewVisible) { return; }
                
                // The preheat window is twice the height of the visible rect
                CGRect preheatRect = self.collectionView.bounds;
                preheatRect = CGRectInset(preheatRect, 0.0f, -0.5f * CGRectGetHeight(preheatRect));
                
                // If scrolled by a "reasonable" amount...
                CGFloat delta = ABS(CGRectGetMidY(preheatRect) - CGRectGetMidY(self.previousPreheatRect));
                if (delta > CGRectGetHeight(self.collectionView.bounds) / 3.0f) {
                    
                    // Compute the assets to start caching and to stop caching.
                    NSMutableArray *addedIndexPaths = [NSMutableArray array];
                    NSMutableArray *removedIndexPaths = [NSMutableArray array];
                    
                    [self computeDifferenceBetweenRect:self.previousPreheatRect andRect:preheatRect removedHandler:^(CGRect removedRect) {
                        NSArray *indexPaths = [self.collectionView aapl_indexPathsForElementsInRect:removedRect];
                        [removedIndexPaths addObjectsFromArray:indexPaths];
                    } addedHandler:^(CGRect addedRect) {
                        NSArray *indexPaths = [self.collectionView aapl_indexPathsForElementsInRect:addedRect];
                        [addedIndexPaths addObjectsFromArray:indexPaths];
                    }];
                    
                    NSArray *assetsToStartCaching = [self assetsAtIndexPaths:addedIndexPaths];
                    NSArray *assetsToStopCaching = [self assetsAtIndexPaths:removedIndexPaths];
                    
                    [self.imageManager startCachingImagesForAssets:assetsToStartCaching
                                                        targetSize:AssetGridThumbnailSize
                                                       contentMode:PHImageContentModeAspectFill
                                                           options:nil];
                    [self.imageManager stopCachingImagesForAssets:assetsToStopCaching
                                                       targetSize:AssetGridThumbnailSize
                                                      contentMode:PHImageContentModeAspectFill
                                                          options:nil];
            
                     self.previousPreheatRect = preheatRect;
                }
            }
            //In your case this computeDifference method changes to handle horizontal scrolling
                - (void)computeDifferenceBetweenRect:(CGRect)oldRect andRect:(CGRect)newRect removedHandler:(void (^)(CGRect removedRect))removedHandler addedHandler:(void (^)(CGRect addedRect))addedHandler
                {
                    if (CGRectIntersectsRect(newRect, oldRect)) {
                        CGFloat oldMaxY = CGRectGetMaxY(oldRect);
                        CGFloat oldMinY = CGRectGetMinY(oldRect);
                        CGFloat newMaxY = CGRectGetMaxY(newRect);
                        CGFloat newMinY = CGRectGetMinY(newRect);
                        if (newMaxY > oldMaxY) {
                            CGRect rectToAdd = CGRectMake(newRect.origin.x, oldMaxY, newRect.size.width, (newMaxY - oldMaxY));
                            addedHandler(rectToAdd);
                        }
                        if (oldMinY > newMinY) {
                            CGRect rectToAdd = CGRectMake(newRect.origin.x, newMinY, newRect.size.width, (oldMinY - newMinY));
                            addedHandler(rectToAdd);
                        }
                        if (newMaxY < oldMaxY) {
                            CGRect rectToRemove = CGRectMake(newRect.origin.x, newMaxY, newRect.size.width, (oldMaxY - newMaxY));
                            removedHandler(rectToRemove);
                        }
                        if (oldMinY < newMinY) {
                            CGRect rectToRemove = CGRectMake(newRect.origin.x, oldMinY, newRect.size.width, (newMinY - oldMinY));
                            removedHandler(rectToRemove);
                        }
                    } else {
                        addedHandler(newRect);
                        removedHandler(oldRect);
                    }
                }
                
            
    
    - (NSArray *)assetsAtIndexPaths:(NSArray *)indexPaths
        {
            if (indexPaths.count == 0) { return nil; }
            
            NSMutableArray *assets = [NSMutableArray arrayWithCapacity:indexPaths.count];
            for (NSIndexPath *indexPath in indexPaths) {
                PHAsset *asset = self.assetsFetchResults[indexPath.item];
                [assets addObject:asset];
            }
            return assets;
        }
    

    The image caching manager heats up with your assets of the desired size and then you can retrieve them from the image caching manager itself.

    Hope it helps you.

    0 讨论(0)
提交回复
热议问题