2013-02-02 81 views
3

我已经得到了iphone的所有图像使用AssetsLibrary.I在ImageView中传递UIImage对象并在滚动视图中显示图像。 iPhone中有超过200张图片,我必须在垂直滚动视图中显示所有图片,而不使用分页。这需要大量时间来显示图像,并且还存在内存问题。是否有任何代码在滚动视图中延迟加载iphone图像Uiscrollview懒加载

+1

看到这么回答http://stackoverflow.com问题/ questions/6786614/uiscrollview-lazy-loading-images-to-reduce-memory-usage-and-avoid-crash – Deepesh

回答

4

我一直对这个最近和已签出的示例代码加载在网络上。没有一个是真正的懒惰加载(尽管声称)或更复杂(不必要的钟声和哨声)比我愿意忍受。 PhotoPicker的Apple WWDC视频似乎显示延迟加载,但似乎更侧重于预先切片图像的平铺,因此没有多大帮助。

我已经结束了做什么是所有aspectThumbnails一次加载,因为它们体积小,不占用这么大的内存,然后从scrollViewDidEndDecelerating按需加载的fullScreenImage表示并重新加载aspectThumbnail的ImageView的不在屏幕上。效果非常流畅和直观,图像稍微粗糙,然后快速(通过背景加载)替换为更高分辨率的图像。

它可能会使用更多的细化 - 也许加载当前页面的全分辨率图像+1 & -1。到目前为止我还没有做到这一点。另外,我并不完全确定我是否使用了最佳模块 - 但没有发现错误。

我从Segue中调用此函数,并在我的根视图控制器的prepareForSegue:方法中设置assetsArray(ALAssets的NSArray)。

// 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

您应该只在当前页面加载一个或两个图像的方向。只在需要时加载图像,保留有限的缓冲区,并在离开缓冲区后删除图像。例如,如果屏幕上显示图像3和4,则应加载图像1,2,5和6。当用户滚动显示图像5和6时,它将保持图像3和4加载,将其内存中的1和2删除,并将加载7和8以创建新的缓冲区。

1

您可以使用GCD块和大中央调度。 在.h文件中声明它

dispatch_queue_t imageQueue_; 

创建下面的代码一个NSMutableDictionary

@property (nonatomic, strong) NSMutableDictionary *thumbnailsCache; 

用它来显示图像。

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

你也可以使用Loa的概念d更多并刷新案例表视图中的示例您可以使用:http://www.cocoacontrols.com/controls/stableviewcontroller –