2013-08-27 40 views
14

Tôi nhận thấy rằng các ứng dụng như Intagram sử dụng UICollectionViews để hiển thị nguồn cấp dữ liệu ảnh. Tôi cũng nhận thấy rằng các ô cho những ảnh này được đặt bằng cách nào đó trên màn hình trước ảnh thực tế được tải xuống hoàn toàn. Sau đó, khi tải xuống hoàn tất, ảnh đó được hiển thị độc đáo trong ô chính xác.UICollectionView - Tải xuống hình ảnh và tải lại hiệu quả dữ liệu, như Instagram

Tôi muốn sao chép chức năng đó, nhưng tôi không biết cách thực hiện.

Tôi hiện đang tải xuống đối tượng JSON lớn mà tôi chuyển đổi thành một mảng NSDictionaries. Mỗi NSDictionary chứa thông tin về mỗi bức ảnh, và trong số các thông tin đó, một URL được trình bày. Tại URL này, tôi có thể tìm thấy hình ảnh tương ứng mà tôi cần tải xuống và hiển thị trong UICollectionViewCells

Hiện tại, tôi lặp lại danh sách này và bắt đầu tải xuống cho mỗi URL tôi thấy. Khi tải xuống hoàn tất, tôi tải lại bộ sưu tập xem bằng cách sử dụng [self.collectionView reloadData]. Nhưng, như bạn có thể tưởng tượng, nếu tôi có 30 ô mà tất cả đều muốn một hình ảnh, có rất nhiều cuộc gọi reloadData.

Tôi đang sử dụng AFNetworking để xử lý các tải về, đây là phương pháp, mà tôi gọi dựa trên URL tôi đã đề cập trước đây:

-(void) downloadFeedImages:(NSString *) photoURL imageDescs:(NSDictionary*)imageDescs photoId:(NSString *)photoID{ 
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES); 
    NSString *directory = [paths objectAtIndex:0]; 

    NSString* foofile = [directory stringByAppendingPathComponent:photoID]; 

    if([[NSFileManager defaultManager] fileExistsAtPath:foofile]){ 
     // IF IMAGE IS CACHED 
     [self.collectionView reloadData]; 
     return; 
    } 

    NSLog(@"photoURL: %@", photoURL); 
    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:photoURL]]; 
    AFImageRequestOperation *operation = [AFImageRequestOperation imageRequestOperationWithRequest:request 
                       imageProcessingBlock:nil 
                          success:^(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image) { 
                           // Save Image 
                           NSLog(@"URL-RESPONSE:%@", image); 
                           NSString *myFile = [directory stringByAppendingPathComponent:photoID]; 

                           NSData *imageData = UIImagePNGRepresentation(image); 
                           [imageData writeToFile:myFile atomically: YES]; 
                           [self.collectionView reloadData]; 
                          } 
                          failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error) { 
                           NSLog(@"ERROR: %@", [error localizedDescription]); 
                          }]; 
    [[WebAPI sharedInstance] enqueueHTTPRequestOperation:operation]; 
} 

Vì vậy về cơ bản, tôi tự hỏi làm thế nào tôi có thể đạt được những chức năng mà Instagram và các ứng dụng tương tự có khi hiển thị nguồn cấp dữ liệu có hình ảnh. Ngoài ra, tôi muốn biết một cách tốt để bắt đầu tải xuống cho mỗi tế bào, và khi tải về được hoàn tất, cập nhật cell đó, không phải vẽ lại quan điểm toàn bộ sử dụng [reloadData]

Cảm ơn

Trả lời

17

Kỹ thuật bạn muốn triển khai được gọi là tải chậm. Vì bạn đang sử dụng AFNetworking, sẽ dễ dàng hơn khi thực hiện việc này trong trường hợp của bạn. Mỗi ô xem bộ sưu tập của bạn cần có một số UIImageView để hiển thị hình ảnh. Sử dụng các loại UIImageView+AFNetworking.h và thiết lập URL hình ảnh chính xác bằng phương pháp gọi

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath 
{ 
    // .... 

    [cell.imageView setImageWithURL:imageURL placeholderImage:[UIImage imageNamed:@"placeholder.png"]]; 

    // ... 
    return cell; 
} 

Placeholder là hình ảnh sẽ được hiển thị cho đến khi hình ảnh cần được tải về. Điều này chỉ đơn giản là sẽ làm công việc cần thiết cho bạn.

Lưu ý: Theo mặc định, yêu cầu URL có chính sách bộ nhớ cache NSURLCacheStorageAllowed và khoảng thời gian chờ là 30 giây và được đặt không xử lý cookie. Để định cấu hình các yêu cầu URL khác nhau, hãy sử dụng setImageWithURLRequest:placeholderImage:success:failure:.

Ngoài ra, để bạn tham khảo, nếu bạn muốn tự thực hiện tải hình ảnh chậm, hãy thực hiện theo số Apple sample code này. Điều này là dành cho UITableView nhưng kỹ thuật tương tự cũng có thể được sử dụng cho UICollectionView.

Hy vọng điều đó sẽ hữu ích!

+0

Tuy nhiên, khi tôi thực hiện điều này, các collectionview khá hacky khi di chuyển. phương pháp này hoàn toàn không đồng bộ? Bất kỳ ý tưởng làm thế nào để làm cho di chuyển của collectionview của tôi ít hacky? =) – Eyeball

+1

@Eyeball Có điều này hoàn toàn không đồng bộ. Có bất kỳ hoạt động nào khác mà bạn đang thực hiện như FileIO trong 'cellForItemAtIndexPath' không? Bất kỳ hoạt động nào có thể gây ra sự tạm dừng đáng chú ý trong chuỗi chính? – Amar

+0

Một điều nữa, bạn không cần tải lại bộ sưu tập cho mọi hình ảnh ngay bây giờ. Mã AFNetworking sẽ quan tâm đến việc làm mới chế độ xem hình ảnh khi hình ảnh được tải xuống và gán cho nó. – Amar

2

sử dụng

[self.collectionView reloadItemsAtIndexPaths:[NSArray arrayWithObject:indexPath]];

thay vì

[self.collectionView reloadData];

đây indexPathNSIndexPath Object cho UICollectionViewCell Object tương ứng

0

Sử dụng sau đây để tải hình ảnh Async trong phòng giam trong ce llForItemAtIndexPath phương pháp đại biểu

let url = URL(string: productModel.productImage) 

    let data = try? Data(contentsOf: url!) 
    DispatchQueue.main.async(execute: { 
     collectionViewCell.imageView.image = UIImage(data: data!) 
    }); 

Thực hiện Nghị định thư "UICollectionViewDataSourcePrefetching" trong bạn ViewController như

lớp ViewController: UIViewController, UICollectionViewDataSourcePrefetching {

Set đại biểu để xem bộ sưu tập của bạn trong kịch bản sau đây (xem hình ảnh đính kèm) hoặc theo lập trình

Trong ViewController củaviewDidLoad phương pháp

collectionView.delegate = self 
collectionView.dataSource = self 
collectionView.prefetchDataSource = self 
Các vấn đề liên quan