Uiscrollview lazy loading

前端 未结 4 1404
别跟我提以往
别跟我提以往 2021-01-06 20:59

I have got all images of iphone using AssetsLibrary.I am passing UIImage object in imageview and display images in scrollview. There are more than 200 images in iphone and i

相关标签:
4条回答
  • 2021-01-06 21:17

    You can use GCD block and grand central dispatch. in your .h file declare it

    dispatch_queue_t imageQueue_;
    

    Create an NSmutableDictionary

    @property (nonatomic, strong) NSMutableDictionary *thumbnailsCache;
    

    Use below Code to Show image.

    NSString *thumbnailCacheKey = [NSString stringWithFormat:@"cache%d",imageIndex];
    
        if (![[self.thumbnailsCache allKeys] containsObject:thumbnailCacheKey]) {
    
            // thumbnail for this row is not found in cache, so get it from remote website
            __block NSData *image = nil;
            dispatch_queue_t imageQueue = dispatch_queue_create("queueForCellImage", NULL);
            dispatch_async(imageQueue, ^{
                NSString *thumbnailURL = [NSString stringWithFormat:@"%@",deal_Class.deal_imageUrl];
                image = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:@"Your URL"]];
                dispatch_async(dispatch_get_main_queue(), ^{
    
    
    
                  imageView.image = [UIImage imageWithData:image];
    
                    if (image) {
                        [self.thumbnailsCache setObject:image forKey:thumbnailCacheKey];
                    }
    
    
                });
            });
    
         //   dispatch_release(imageQueue);
    
    
        } else {
    
            // thumbnail is in cache
            NSData *image = [self.thumbnailsCache objectForKey:thumbnailCacheKey];
            dispatch_async(dispatch_get_main_queue(), ^{
                imageview.image = [UIImage imageWithData:image];
            });
        }
    
    0 讨论(0)
  • 2021-01-06 21:31

    I've been working on this recently and have checked out loads of example code on the web. None of it really did lazy loading (despite the claim) or had much more complexity (needless bells and whistles) than I was willing to put up with. The Apple WWDC videos for PhotoPicker appear to show lazy loading but seem more focused on tiling of pre-sliced up images, so not much help there.

    What I've ended up doing is to load all the aspectThumbnails at once, since they are small and don't take up that much memory and then load the fullScreenImage representation on demand from scrollViewDidEndDeceleratingand reload the aspectThumbnail for the imageView going off-screen. The effect is very fluid and visually, the image comes in a little rough and then quickly (through background loading) is replaced with the higher resolution image.

    It can probably use more refinement - perhaps loading full resolution images for the currentPage +1 & -1. I haven't got around to that as yet. Also, I'm not entirely sure if my use of blocks in optimal – but not getting an errors.

    I call this from a Segue and set the assetsArray (NSArray of ALAssets) from within the prepareForSegue: method on my root viewController.

    //  ScrollViewController.h
    #import <UIKit/UIKit.h>
    #import <AssetsLibrary/AssetsLibrary.h>
    
    @interface ScrollViewController : UIViewController <UIScrollViewDelegate>
    
    @property (weak, nonatomic) IBOutlet UIScrollView *scrollView;
    @property (strong, atomic) ALAssetsLibrary* assetLibrary;
    @property (nonatomic,strong)NSMutableArray* assetsArray;
    @end
    

    //ScrollViewController.m

    #import "ScrollViewController.h"
    
    @interface ScrollViewController ()
    
    @property (nonatomic,assign) CGSize currentImageSize;
    @property (nonatomic, assign)int currentPages;
    @property (nonatomic, assign)int currentPageNum;
    @property (nonatomic, strong)UIImage* placeHolder;
    @end
    
    
    
    @implementation ScrollViewController
    
    
    - (void)viewDidLoad
    {
        [super viewDidLoad];
    
        //self.placeHolder = [UIImage imageNamed:@"loader.jpg"];
        self.scrollView.delegate = self;
    }
    
    - (void)viewWillAppear:(BOOL)animated
    {
        [super viewWillAppear:animated];
    
        if (self.assetsArray != nil) {
            self.currentPages = [self.assetsArray count];
    
            CGSize size = self.scrollView.frame.size;
            int num = self.currentPages;
    
            self.scrollView.contentSize=CGSizeMake(size.width*num, size.height);
    
            [self loadThumbnails];
    
            self.currentPageNum = 0;
            [self loadFullScreenImageByIndex:self.currentPageNum];
        }
    }
    
    -(void)loadThumbnails
    {
        int pageCount = self.currentPages;
        CGSize size = self.scrollView.frame.size;
        self.scrollView.contentSize=CGSizeMake(size.width*pageCount, size.height);
    
        for (int i = 0; i < pageCount; i++) {
    
            ALAsset *asset = [self.assetsArray objectAtIndex:i];//
            CGRect imageViewFrame;
    
            // x offset is determined by arrayIndex
            imageViewFrame.origin.x = self.scrollView.frame.size.width * i;
            imageViewFrame.origin.y = 0;
            imageViewFrame.size = self.scrollView.frame.size;
    
            self.currentImageSize = imageViewFrame.size; // THIS IS WRONG
    
            UIImage *image = [[UIImage alloc] initWithCGImage:asset.aspectRatioThumbnail];
            UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
            imageView.clipsToBounds = YES;
            imageView.contentMode = UIViewContentModeScaleAspectFill;
            imageView.frame = imageViewFrame;
            imageView.tag = i+1;// start tags at 1
    
            [self.scrollView addSubview:imageView];
        }
    }
    
    
    - (void)viewDidUnload {
        [self setScrollView:nil];
        [super viewDidUnload];
    }
    
    - (void)loadFullScreenImageByIndex:(int)index
    {
        int arrayIndex = index;
        int tagNumber = index+1;
        ALAsset *asset = [self.assetsArray objectAtIndex:arrayIndex];
    
        __weak typeof(self) weakSelf = self;
    
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
            UIImage *tmpImage = [[UIImage alloc] initWithCGImage:asset.defaultRepresentation.fullScreenImage];
    
            __strong __typeof__(weakSelf) strongSelf = weakSelf;
            if ([strongSelf.scrollView viewWithTag:tagNumber] != nil){
    
                dispatch_async(dispatch_get_main_queue(), ^{
                    __strong __typeof__(weakSelf) strongSelf = weakSelf;
                    if ([strongSelf.scrollView viewWithTag:tagNumber]!= nil){
                        UIImageView * tmpImageView = (UIImageView*)[strongSelf.scrollView viewWithTag:tagNumber];
                        tmpImageView.image = tmpImage;
                    }
                });
            }
        });
    }
    
    - (void)loadThumbnailImageByIndex:(int)index
    {
        int arrayIndex = index;
        int tagNumber = index+1;
    
        ALAsset *asset = [self.assetsArray objectAtIndex:arrayIndex];//
    
        __weak typeof(self) weakSelf = self;
    
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
            UIImage *tmpImage = [[UIImage alloc] initWithCGImage:asset.aspectRatioThumbnail];        
            __strong __typeof__(weakSelf) strongSelf = weakSelf;
            if ([strongSelf.scrollView viewWithTag:tagNumber] != nil){
    
                dispatch_async(dispatch_get_main_queue(), ^{
                    __strong __typeof__(weakSelf) strongSelf = weakSelf;
                    if ([strongSelf.scrollView viewWithTag:tagNumber]!= nil){
                        UIImageView * tmpImageView = (UIImageView*)[strongSelf.scrollView viewWithTag:tagNumber];
                        tmpImageView.image = tmpImage;
                    }
                });
            }
        });
    }
    
    - (void)manageImages
    {
        int currentPage = (self.scrollView.contentOffset.x / self.currentImageSize.width);
    
        if (currentPage != self.currentPageNum){
            [self loadThumbnailImageByIndex:self.currentPageNum]; //pg no longer visible so load thumb
            [self loadFullScreenImageByIndex:currentPage]; // load full
            self.currentPageNum = currentPage;// store
        }
    }
    
    - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
    {
        [self manageImages];
    }
    
    0 讨论(0)
  • 2021-01-06 21:34

    There are many tutorial available for this.

    Let me point some of them:

    How To Use UIScrollView to Scroll and Zoom Content

    Scroll Lazy Image Load for iOS

    If you dont have problem in using someone's code
    DMLazyScrollView : Lazy Loading UIScrollView (with infinite page scrolling)

    0 讨论(0)
  • 2021-01-06 21:42

    You should only have loaded the images on the current page plus one or two in either direction. Only load images when you need them, keeping a limited buffer, and remove images after they have left the buffer. For example, if images 3 and 4 are on screen, images 1,2,5, and 6 should be loaded. When the user scrolls such that images 5 and 6 are on screen, it will keep images 3 and 4 loaded, will remove 1 and 2 from its memory, and will load 7 and 8 to make a new buffer.

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