Load image to UICollectionView Asynchronously?

后端 未结 3 2089
长情又很酷
长情又很酷 2020-12-29 15:46

How can i load images to a UICollectionview asynchronously? Inside following method?

- (PSTCollectionViewCell *)collectionView:(PSTCollectionVie         


        
3条回答
  •  难免孤独
    2020-12-29 16:22

    Trying to answer your main question "How can i load images to a UICollectionview asynchronously?"

    I would suggest solution offered by "Natasha Murashev" here, which worked nicely for me and it's simple.

    If here imgURL = [allImage objectAtIndex:k]; in allImage property you keep array of URLs, then update your collectionView:cellForItemAtIndexPath: method like this:

    - (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 method downloadImageWithURL:completionBlock: to your class, which will load images asynchronously and update cells in CollectionView automatically when images are successfully downloaded.

    - (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 you try to preload images before view appears so maybe my solution isn't what you what, but from your question it's hard to say. Any how, you can achieve what you want with this as well.

    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 sample:

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

提交回复
热议问题