非同期画像の読み込みにUIImageView+AFNetworking
カテゴリを使用しています。すべて正常に動作しますが、いくつか試してみましたが、ダウンロードした画像に従ってセルの高さを変更しても成功しませんでした。画像をセルの幅に合わせて高さを変更したいのですが、その方法がわかりません。イメージがダウンロードされた行をリロードしようとしましたが、それによってcellForRowAtIndexPath
が再度起動され、すべてが再設定されるなどの原因になります。ほとんど再帰的です。
新しい画像サイズの差を計算してNSMutableArray
に保存し、UIImageViewのsetImageWithURLRequest:placeholderImage:success:
の成功ブロックに行を再読み込みしています。
heightForRowAtIndexPath
のいくつかの行の正しい高さを取得しましたが、テーブルが奇妙に動作し始め、すべてがオーバーレイされています。
何か案は?
ありがとう!
[〜#〜]編集[〜#〜]
やがて江関の答えを使いました。また、このトピックに関する投稿を作成し、この手法を使用するサンプルアプリを作成しました。
ここ でチェックしてください。
ダウンロードした画像をメモリまたはディスクに保存する必要があるため、次回このURLから画像を取得しようとすると、キャッシュから受信します。
したがって、それを行う場合は、次のようなことを行う必要があります。
[tableView beginUpdates];
[tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
[tableView endUpdates];
また、テーブルビューデータソースのこのメソッドで新しいセルの高さを返す必要があります。
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
AFNetworking
の代わりに SDWebImageライブラリ を使用することをお勧めします。これは、画像をmemcacheとディスクにキャッシュでき、非常に使いやすいためです。したがって、それを使用することにした場合、ダウンロード画像のコードは次のようになります。
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
...
[cell.imageView setImageWithURL:[NSURL URLWithString:@"http://www.domain.com/path/to/image.jpg"]
placeholderImage:[UIImage imageNamed:@"placeholder.png"]
success:^(UIImage *image, BOOL cached) {
// save height of an image to some cache
[self.heightsCache setObject:[NSNumber numberWithFloat:imHeight]
forKey:urlKey];
[tableView beginUpdates];
[tableView reloadRowsAtIndexPaths:@[indexPath]
withRowAnimation:UITableViewRowAnimationFade];
[tableView endUpdates];
}
failure:^(NSError *error) {... failure code here ...}];
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
// try to get image height from your own heights cache
// if its is not there return default one
CGFloat height = [[self.heightsCache objectForKey:urlKeyFromModelsArrayForThisCell] floatValue];
...
return newHeight;
}
私にとってこれはうまくいきます:
キャッシュイメージが使用可能かどうかを確認し、使用可能かどうかをイメージに設定します。使用できない場合は、ダウンロードしてから、リロードインデックスパスを呼び出してテーブルのレイアウトをリセットします。
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *broadcastTableCellIdentifier = @"BlockbusterTableViewCell";
BlockbusterTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:broadcastTableCellIdentifier];
if (cell == nil) {
cell = [[BlockbusterTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:broadcastTableCellIdentifier];
}
[self configureCell:cell atIndexPath:indexPath];
return cell;
}
-(void)configureCell:(BlockbusterTableViewCell*)cell atIndexPath:(NSIndexPath*)indexPath{
SportData *data = [self.webShared.arrSportsData objectAtIndex:self.selectedEvent];
BroadcastData *broadcastData = [data.broadcastData objectAtIndex:indexPath.row];
NSURLRequest *urlRequest = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:broadcastData.image]];
AFImageDownloader *downloader = [UIImageView sharedImageDownloader];
id <AFImageRequestCache> imageCache = downloader.imageCache;
UIImage *cacheimage = [imageCache imageforRequest:urlRequest withAdditionalIdentifier:nil];
if (cell.imgBroadcast.image != cacheimage) {
[cell.imgBroadcast setImageWithURLRequest:urlRequest placeholderImage:[UIImage imageNamed:@"placeholder_smaller"] success:^(NSURLRequest * _Nonnull request, NSHTTPURLResponse * _Nullable response, UIImage * _Nonnull image) {
cell.imgBroadcast.image = image;
[self.tableViewBroadcast beginUpdates];
[self.tableViewBroadcast reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
[self.tableViewBroadcast endUpdates];
} failure:^(NSURLRequest * _Nonnull request, NSHTTPURLResponse * _Nullable response, NSError * _Nonnull error) {
}];
}
else{
cell.imgBroadcast.image =cacheimage;
}
cell.lblTitle.text = broadcastData.title;
cell.lblText.text = broadcastData.text;
cell.lblEventDateTime.text = [self eventTime:broadcastData.eventTime];
}