2011-10-21 30 views
8

Tôi có một UITableView với các ô tùy chỉnh. Tôi tải hình ảnh không đồng bộ bằng Grand Central Dispatch. Tất cả mọi thứ hoạt động tốt, nhưng khi tôi di chuyển xuống, hình ảnh được tải trước đó được hiển thị cho đến khi hình ảnh mới được tải xuống. Đây là mã của tôi:GCD UITableView tải hình ảnh không đồng bộ, các ô sai được tải cho đến khi tải xuống hình ảnh mới

if (![[NSFileManager defaultManager] fileExistsAtPath:[path stringByAppendingPathComponent:@"image.png"]]) 
{ 
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul); 
    dispatch_async(queue, ^{ 
     NSString *url=[pat stringByAppendingPathComponent:@"comments.txt"]; 
     NSString *u=[NSString stringWithContentsOfFile:url encoding:NSUTF8StringEncoding error:nil]; 
     NSURL *imageURL=[NSURL URLWithString:u]; 
     NSData *image=[NSData dataWithContentsOfURL:imageURL]; 
     [image writeToFile:[pat stringByAppendingPathComponent:@"image.png"] atomically:YES]; 
     dispatch_sync(dispatch_get_main_queue(), ^{ 
      cell.imageView.image=[UIImage imageWithContentsOfFile:[pat stringByAppendingPathComponent:@"image.png"]]; 
      [cell setNeedsLayout]; 
      NSLog(@"Download"); 
     }); 
    }); 
} 
else 
{ 
    NSLog(@"cache"); 
    cell.imageView.image=[UIImage imageWithContentsOfFile:[pat stringByAppendingPathComponent:@"image.png"]]; 
} 

Bất kỳ đề xuất nào được đánh giá cao. P.S. Tôi sử dụng lại các ô

Trả lời

18

Thay vì chụp ô bạn cần phải nắm bắt những con đường chỉ số, sau đó nhận được các tế bào trở lại sử dụng:

UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath]; 

Bằng cách đó, nếu các tế bào tại là tắt màn hình, bạn sẽ nhận được con số không trở lại và hình ảnh sẽ không được đặt trên ô sai.

Điều khác bạn cần thêm sau dispatch_async()cell.imageView.image=somePlaceholderImage.

ví dụ .:

if (![[NSFileManager defaultManager] fileExistsAtPath:[path stringByAppendingPathComponent:@"image.png"]]) 
{ 
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul); 
    dispatch_async(queue, ^{ 
     NSString *url=[pat stringByAppendingPathComponent:@"comments.txt"]; 
     NSString *u=[NSString stringWithContentsOfFile:url encoding:NSUTF8StringEncoding error:nil]; 
     NSURL *imageURL=[NSURL URLWithString:u]; 
     NSData *image=[NSData dataWithContentsOfURL:imageURL]; 
     [image writeToFile:[pat stringByAppendingPathComponent:@"image.png"] atomically:YES]; 
     dispatch_sync(dispatch_get_main_queue(), ^{ 
      UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath]; 
      cell.imageView.image=[UIImage imageWithContentsOfFile:[pat stringByAppendingPathComponent:@"image.png"]]; 
      [cell setNeedsLayout]; 
      NSLog(@"Download"); 
     }); 
    }); 
    cell.imageView.image=[UIImage imageNamed:@"placeholder"]; 
} 
else 
{ 
    NSLog(@"cache"); 
    cell.imageView.image=[UIImage imageWithContentsOfFile:[pat stringByAppendingPathComponent:@"image.png"]]; 
} 
+0

cảm ơn bạn đã trả lời ... nhưng, bạn có thể cung cấp một số mã mẫu không? – blackhawk4152

+0

Cập nhật câu trả lời của tôi – hypercrypt

+0

cảm ơn, người đàn ông! chỉ là những gì tôi muốn – blackhawk4152

2

Trong số - (void)tableView:(UITableView *)aTableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath { Bạn cần xóa hình ảnh hoặc đặt lại hình ảnh đó cho ô quay của mình. Vì các hàng trong bảng được sử dụng lại, đây là hành vi bạn sẽ thấy.

2

Không UITableViewCell xác định - (void) prepareForReuse cho mục đích đó? Ghi đè lên và xóa hình ảnh của bạn Xem trong đó.

+0

Theo [tài liệu] (http://developer.apple.com/library/ios/#documentation/uikit/reference/UITableViewCell_Class/Reference/Reference.html#//apple_ref/occ/instm/UITableViewCell/prepareForReuse) bạn không được phép chạm vào nội dung bên trong preparForReuse. Thay vào đó, bạn nên đặt lại nội dung trong cellForRowAtIndexPath. –

Các vấn đề liên quan