Обновление UITableViewCell после извлечения данных изображения с помощью dispatch_async
Я пишу приложение, которое показывает TableView с записями, которые содержат изображения. Я пытаюсь получить изображение, выполнив эту строку кода внутри cellForRowAtIndexPath
метод:
cell.detailTextLabel.text = [artistData objectForKey:generesKey];
dispatch_async(backgroundQueue, ^{
NSURL *url_img = [NSURL URLWithString:[artistData objectForKey:pictureKey]];
NSData* data = [NSData dataWithContentsOfURL:
url_img];
cell.imageView.image = [UIImage imageWithData:data];
[self performSelectorOnMainThread:@selector(refreshCell:) withObject:cell waitUntilDone:YES];
});
После настройки изображения я выполняю селектор, который содержит:
-(void)refreshCell:(UITableViewCell*)cell{
[cell setNeedsDisplay];
[self.view setNeedsDisplay];
[self.tableViewOutlet setNeedsDisplay];
}
И изображение не отображается, но когда я нажимаю на ячейку или прокручиваю весь список, изображения отображаются. Почему мой вид не освежает? Я что-то пропустил?
3 ответа
Вы всегда можете перезагрузить ячейку, позвонив [self.tableView reloadRowsAtIndexPaths@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
Чтобы предотвратить бесконечный цикл после успешной загрузки изображения, вам нужно будет кэшировать результаты. Как долго вы кеша зависит от вас.
NSCache *imageCache = [[NSCache alloc] init];
imageCache.name = @"My Image Cache";
UIImage *image = [imageCache objectForKey:url_img];
if (image) {
cell.imageView.image = image;
} else {
// Do your dispatch async to fetch the image.
// Once you get the image do
[imageCache setObject:[UIImage imageWithData:data] forKey:url_img];
}
Вам нужно, чтобы imageCache был свойством на уровне ViewController. Не создавайте один каждый раз вcellForRowAtIndexPath
Должно быть достаточно позвонить setNeedsLayout()
на камеру.
В Swift 4 это выглядит так:
DispatchQueue.global().async {
let data = try? Data(contentsOf: URL(string: imageUrl)!)
DispatchQueue.main.async {
cell.imageView?.image = UIImage(data: data!)
cell.setNeedsLayout()
}
}
Это может быть связано с взаимодействием с пользовательским интерфейсом из фоновой очереди. Попробуй это:
dispatch_async(backgroundQueue, ^{
NSURL *url_img = [NSURL URLWithString:[artistData objectForKey:pictureKey]];
NSData* data = [NSData dataWithContentsOfURL:url_img];
dispatch_async(dispatch_get_main_queue(), ^{
cell.imageView.image = [UIImage imageWithData:data];
});
});