2013-08-03 101 views
6

如何將圖像加載到UICollectionview異步? 裏面下面的方法?將圖像加載到UICollectionView異步?

- (PSTCollectionViewCell *)collectionView:(PSTCollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { 

bookImage = [UIImage imageWithContentsOfFile:[NSString stringWithFormat:@"%@/%@", docPath, [[preview objectAtIndex:indexPath.row] lastPathComponent]]]; 
[[cell grid_image] setImage:bookImage]; 

} 

viewDidLoad中()我使用下面的非同步調用來加載圖像, 「預覽」 NSMutablearray

dispatch_queue_t imageLoadQueue = dispatch_queue_create("com.GMM.assamkar", NULL); 

dispatch_async(imageLoadQueue, ^{ 
    //Wait for 5 seconds... 
    usleep(1000000); 
    docPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0]; 


    for(int k=0; k <[allImage count] ;k++){ 


     imgURL = [allImage objectAtIndex:k]; 
     [imagePreview addObject:imgURL]; 
     imgData=[NSData dataWithContentsOfURL:[NSURL URLWithString:imgURL]]; 


     [imgData writeToFile:[NSString stringWithFormat:@"%@/%@", docPath, [allImage lastPathComponent]] atomically:YES]; 

    } 

    [[self collectionView] reloadData]; 


}); 

請幫me..Now其花費過多時間用於加載...

+0

什麼時間太長特別?圖像大小是多少? – Wain

+0

你應該使[[self collectionView] reloadData];在主線程中。這不是一個答案。它只是評論。 – stosha

+0

使用EGOImageView: https://github.com/enormego/EGOImageLoading –

回答

0

此代碼創建串行隊列:

dispatch_queue_t imageLoadQueue = dispatch_queue_create("com.GMM.assamkar", NULL); 

,因此每個任務IN QUEUE在相同的線程中連續執行。因此,對於加載的每個任務而言,您的單個工作線程都會由睡眠維持,從而減慢所有加載過程。

使用異步併發隊列使用類似的東西:

dispatch_queue_t imageLoadQueue = dispatch_queue_create("com.GMM.assamkar", DISPATCH_QUEUE_CONCURRENT); 
+0

因此,主線程上使用reloadData。像那樣dispatch_async(dispatch_get_main_queue(),^ {// reloadData}); – user2595925

+0

我想我應該使用新的延遲加載方法disaplay我PSTCollectionView – Navi

-1

爲您的要求使用延遲加載文件。

LazyLoad.h
LazyLoad.m

使用它們像這樣

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

    [cell addSubview:[self addViewWithURL:@"http://openwalls.com/image/399/explosion_of_colors_1920x1200.jpg" NFrame:CGRectMake(0, 0, 50, 50)]]; 

    cell.backgroundColor=[UIColor blueColor]; 
    return cell; 
} 

-(UIView*)addViewWithURL:(NSString*)urlStr NFrame:(CGRect)rect 
{ 
    LazyLoad *lazyLoading; 

    lazyLoading = [[LazyLoad alloc] init]; 
    [lazyLoading setBackgroundColor:[UIColor grayColor]]; 
    [lazyLoading setFrame:rect]; 

    [lazyLoading loadImageFromURL:[NSURL URLWithString:urlStr]]; 
    return lazyLoading; 
} 

Download Demo Here

+0

我如何可以顯示UICollectionview cell.imageview.image圖像,這就是我的問題 – Navi

+0

cell.imageview.image財產不存在的CollectionView只在tableView.MyCode會異步加載圖像並作爲子視圖添加到collectionView單元格中。 – Warewolf

+0

添加mycode的與http://stackoverflow.com/a/17856406/1305001或u需要使用自定義單元格,而不是 – Warewolf

8

試圖回答您的主要問題: 「我怎樣才能加載圖像到UICollectionview異步?」

我建議你通過「娜塔莎Murashevhere,這很好地爲我工作提供的解決方案,它的簡單。

如果這裏imgURL = [allImage objectAtIndex:k];allImage財產你把網址的陣列,那麼像這樣的更新collectionView:cellForItemAtIndexPath:方法:

- (PSTCollectionViewCell *)collectionView:(PSTCollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath 
{ 
    NSURL *url = [NSURL URLWithString:[allImage objectAtIndex:indexPath]]; 

    [self downloadImageWithURL:url completionBlock:^(BOOL succeeded, NSData *data) { 
     if (succeeded) { 
      cell.grid_image.image = [[UIImage alloc] initWithData:data]; 
     } 
    }]; 
} 

相加法downloadImageWithURL:completionBlock:到您的類,它會自動加載異步圖像和更新細胞的CollectionView當圖像被成功下載時。

- (void)downloadImageWithURL:(NSURL *)url completionBlock:(void (^)(BOOL succeeded, NSData *data))completionBlock 
{ 
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; 
    [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) { 
     if (!error) { 
      completionBlock(YES, data); 
     } else { 
      completionBlock(NO, nil); 
     } 
    }]; 
} 

我看你嘗試預載圖像前視圖出現,所以也許我的解決方案是不是你的東西,但是從你的問題就很難說了。任何方式,你都可以實現你想要的。

Swift 2.2 Swift中的解決方案。

public typealias ImageFetchCompletionClosure = (image: UIImage?, error: NSError?, imageURL: NSURL?) -> Void 

extension String { 
    func fetchImage(completionHandler: (image: UIImage?, error: NSError?, imageURL: NSURL?) -> Void) { 
     if let imageURL = NSURL(string: self) { 
      NSURLSession.sharedSession().dataTaskWithURL(imageURL) { data, response, error in 
       guard 
        let httpURLResponse = response as? NSHTTPURLResponse where httpURLResponse.statusCode == 200, 
        let mimeType = response?.MIMEType where mimeType.hasPrefix("image"), 
        let data = data where error == nil, 
        let image = UIImage(data: data) 
        else { 
         if error != nil { 
          completionHandler(image: nil, error: error, imageURL: imageURL) 
         } 
         return 
       } 
       dispatch_sync(dispatch_get_main_queue()) {() -> Void in 
        completionHandler(image: image, error: nil, imageURL: imageURL) 
       } 
      }.resume() 
     } 
    } 
} 

用法示例:

"url_string".fetchImage { (image, error, imageURL) in 
     // handle different results, either image was downloaded or error received 
    } 
+0

是不是像細胞可以重複使用,你有效地覆蓋與其他一些圖像數據單元格?另外單元格在你的示例中是未定義的;) – Andy

+0

它主要是爲了回答如何異步加載圖像,而不是如何使用單元格高效工作:)雖然,謝謝指出它。 – Jonauz