2015-09-05 17 views
5

Xin chào vấn đề của tôi là khi tôi di chuyển TableView hình ảnh sẽ xuất hiện trong một ô sai, sau một vài giây, hình ảnh chính xác xuất hiện.UITableView - hình ảnh di động thay đổi khi di chuyển

đây là mã của tôi

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ 
static NSString *CellIdentifier = @"Cell"; 
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 

// Configure the cell... 
if (cell == nil) { 
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] ; 
} 

[cell setOpaque:NO]; 
[cell setBackgroundColor: [UIColor clearColor]]; 

PlaceData *data = [tableData objectAtIndex:indexPath.row]; 
UILabel *nameLabel = (UILabel *)[cell viewWithTag:100]; 
UILabel *sciNameLabel = (UILabel *)[cell viewWithTag:200]; 
UIImageView *thumbnailImageView = (UIImageView *)[cell viewWithTag:300]; 
nameLabel.text = data.name; 
sciNameLabel.text = data.scientific_name; 


// get a dispatch queue 
dispatch_queue_t concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); 
// this will start the image loading in bg 
dispatch_async(concurrentQueue, ^{ 
    NSURL *urlToPicture = [NSURL URLWithString:[NSString stringWithFormat:@"%@", data.thumbnail]]; 
    NSData *imgData = [NSData dataWithContentsOfURL:urlToPicture options:0 error:nil]; 

    // This will set the image when loading is finished 
    dispatch_async(dispatch_get_main_queue(), ^{ 
     UIImage *tmpImage = [[UIImage alloc] initWithData:imgData]; 
     thumbnailImageView.image = tmpImage; 
     //dispatch_release(concurrentQueue); 
     }); 
    }); 

     return cell; 
} 

hãy giúp tôi

+0

https://stackoverflow.com/questions/43866409/collectionview-in-tableviewcell-scroll-isnt-mịn-in-swift3/43907018 # 43907018 – Sanju

Trả lời

18

Bạn có thể thử thêm mã sau vào cellForRowAtIndexPath của bạn -

1) Gán một giá trị chỉ số để tế bào tùy chỉnh của bạn. Ví dụ:

cell.tag = indexPath.row 

2) Trên chủ đề chính, trước khi chỉ định hình ảnh, hãy kiểm tra xem hình ảnh có thuộc ô tương ứng hay không bằng cách khớp với thẻ đó.

dispatch_async(dispatch_get_main_queue(), ^{ 
    if(cell.tag == indexPath.row) { 
     UIImage *tmpImage = [[UIImage alloc] initWithData:imgData]; 
     thumbnailImageView.image = tmpImage; 
    }}); 
}); 
+2

cảm ơn câu trả lời !! những điều này giúp tôi giải quyết vấn đề. –

+1

Câu trả lời hay nhất, Giải quyết được vấn đề của tôi – Jan

4

Bạn đang sử dụng lại các tế bào cũ, đó là một điều tốt. Tuy nhiên, bạn không khởi tạo hình ảnh trong khung nhìn hình ảnh của ô, đó không phải là một điều tốt. Những gì bạn mô tả xảy ra vì một ô cũ, với một hình ảnh đã được tải cho ô đó, được sử dụng cho ô mới. Sau đó, bạn sẽ tải hình ảnh của ô đó ở chế độ nền (trong đó, một lần nữa, là tốt) nhưng phải mất một vài phút để hình ảnh đó tải đầy đủ. Trong khi chờ đợi, hình ảnh đã được tải trên ô cũ, được hiển thị (và đó là lý do bạn nhìn thấy hình ảnh sai trong ô đó, trong một vài phút).

Giải pháp? thêm hoặc

thumbnailImageView.image = nil 

hoặc

thumbnailImageView.image = someDefaultImageWhileYourRealOneLoads 

ngay trước dispatch_queue_t concurrentQueue ....

Bằng cách đó, bạn sẽ không thấy hình ảnh cũ (không có liên quan) trong khi hình ảnh thực tải.

Tôi hy vọng điều này sẽ hữu ích. Chúc may mắn.

+0

cảm ơn câu trả lời nhưng nó vẫn hiển thị hình ảnh cũ –

+1

Cảm ơn, đã tìm kiếm giải pháp trong vài giờ và của bạn là cách dễ nhất và tốt nhất một! – DazChong

3

Khi becauase ImageView của bạn đang được tải trong một cuộc gọi công văn async KHÔNG nằm trên chủ đề chính và đang được gọi trong một số chủ đề khác để có sự chậm trễ trong việc tìm nạp dữ liệu từ URL và sau đó chuyển đổi nó thành UIImage . Quá trình này mất một chút thời gian như bạn biết nhưng bạn đang di chuyển tableview với tốc độ nhanh hơn. Và như bạn biết, cellForRowAtIndexPath sẽ sử dụng lại bất kỳ ô nào nằm ngoài cửa sổ để ô được tái sử dụng có thể KHÔNG tìm nạp được imagedata mà nó đã được sử dụng trước đó khi nó ở trong cửa sổ. Vì vậy, nó tải dữ liệu sai và sau đó một lần nữa khi async được kích hoạt cho ô cụ thể mà ô tải hình ảnh đó nhưng có sự chậm trễ.

Để khắc phục tính năng này như Chronch chỉ nó ra u có thể rời khỏi ImageView như nil HOẶC bạn có thể sử dụng AFNetworking 's loại di UIImageView riêng trong đó có một lớp tuyệt vời để tải hình ảnh ImageView khá thanh lịch

Tôi sẽ để lại ua liên kết với nó AFNetworking

+0

Cảm ơn bạn đã trả lời –

1

Tôi sẽ thực hiện tất cả các ràng buộc dữ liệu của mình tại - tableView:willDisplayCell:forRowAtIndexPath: chỉ vì tại cellForRowAtIndexPath ô của bạn chưa được vẽ. Một giải pháp khác mà bạn có thể sử dụng là AFNetworking giống như một người khác được đề cập trước tôi.

+1

cảm ơn trả lời –

1

Swift 3.0

DispatchQueue.main.async(execute: {() -> Void in 

    if cell.tag == indexPath.row { 
     var tmpImage = UIImage(data: imgData) 
     thumbnailImageView.image = tmpImage 
    } 
}) 
0

Đừng lo lắng thêm hai dòng và cảm thấy tự

cell.thumbnailimages.image=nil 

    cell.thumbnailimages.setImageWith(imageurl!) 

tôi nghĩ rằng hai dòng sau giải quyết vấn đề của bạn Cảm ơn trước

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