Load image in UICollectionView asynchronously?

How can I upload images to a UICollectionview asynchronously? Inside the following method?

 - (PSTCollectionViewCell *)collectionView:(PSTCollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { bookImage = [UIImage imageWithContentsOfFile:[NSString stringWithFormat:@"%@/%@", docPath, [[preview objectAtIndex:indexPath.row] lastPathComponent]]]; [[cell grid_image] setImage:bookImage]; } 

In viewdidload (), I use the following asynchronous call to load images into the "preview" 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]; }); 

Please help me .. Now its too much time to download ...

+6
source share
3 answers

Trying to answer your basic question, "How can I upload images to UICollectionview asynchronously?"

I propose the solution proposed by Natasha Murashev here , which worked great for me, and it's simple.

If here imgURL = [allImage objectAtIndex:k]; the allImage property stores an array of URLs, update your collectionView:cellForItemAtIndexPath: method as follows:

 - (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]; } }]; } 

And add the downloadImageWithURL:completionBlock: method to your class, which will load images asynchronously and update cells in CollectionView automatically when the images are successfully loaded.

 - (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); } }]; } 

I see that you are trying to preload the images before the presentation appears, so maybe my solution is not that you are, but it is hard to say from your question. Be that as it may, you can also achieve what you want.

Swift 2.2 Solution in 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() } } } 

Usage example:

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

This code creates a queue queue:

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

therefore, each IN QUEUE task runs in the same thread in a row. Therefore, your only workflow is supported by sleep for each download task, which slows down the entire download process.

Use the CONCURRENT asynchronous queue using something like this:

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

Use Lazy Load File for your requirement.

LazyLoad.h
LazyLoad.m

Use them like that

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

-1
source

Source: https://habr.com/ru/post/950948/


All Articles