複数の画像をダウンロードし、それぞれをUITableViewCell内のUIImageViewにロードするベストプラクティスは何ですか? 特に、ダウンロード後に UIImageview のサイズを変更/置換するか、UIImageView に収まるように画像のサイズを変更する必要があります。UIImageView のサイズ変更/置換は、UITableViewCell のサイズ変更/置換にも注意してください。それは何か問題を引き起こしますか?
2 に答える
いくつかの考え:
UIImageView
複数の画像をダウンロードし、それぞれを内の にロードするベスト プラクティスは何UITableViewCell
ですか?
イメージのダウンロードに関するベスト プラクティスは次のとおりです。
遅延読み込みを確実に利用してください (必要なときに画像を読み込みます)。
イメージを非同期でダウンロードします。
ダウンロード手法が、表示されなくなったテーブルビュー セルの要求をキャンセルすることを確認してください。たとえば、ネットワークが低速でテーブル ビューをすばやく下にスクロールする場合、表示されなくなった画像をダウンロードするためにデバイスを拘束したくはありません。
サーバーへの同時リクエストが多すぎないようにしてください。iOS では、5 つまたは 6 つの同時リクエストを超えると、後続のリクエストは前のリクエストが完了するまでフリーズします。最悪のシナリオでは、後続のリクエストがタイムアウトして実際に失敗し始めます。
結果をキャッシュします。少なくとも、それらをメモリにキャッシュします。それらを永続ストレージ (別名「ディスク」) にキャッシュすることもできます。
非同期操作やキャッシュなどの独自のコードを作成する場合はNSOperationQueue
、GCD の代わりに使用して、バックグラウンド リクエストの数を制限し、リクエストをキャンセル可能にすることができます。NSCache
画像をキャッシュするために使用します。また、おそらくUITableViewCell
サブクラス (またはカテゴリ) を使用してweak
、「前の」操作への参照を保存できるようにして、不完全な以前の要求をキャンセルできるようにします。
ご覧のとおり、これは重要な問題です。またはUIImageView
の一部として利用可能なカテゴリなど、既存のカテゴリを使用することをお勧めします。私見ですが、前者の方が少しリッチです (たとえば、ディスク キャッシュを提供します) が、多くのネットワーキングを行っていて、単一のフレームワークに固執したい場合は、 も素晴らしい仕事をします。SDWebImage
AFNetworking
AFNetworking
後であなたは尋ねます:
特に、ダウンロード後に UIImageview のサイズを変更/置換するか、UIImageView に収まるように画像のサイズを変更する必要があります。UIImageView のサイズ変更/置換は、UITableViewCell のサイズ変更/置換にも注意してください。それは何か問題を引き起こしますか?
画像がセルのサムネイル ビューに必要なサイズよりも大きい場合は、2 つの方法があります。まず、 または を使用できます
contentMode
(UIViewContentModeScaleAspectFit
またUIViewContentModeScaleAspectFill
、 を使用する場合はAspectFill
、 にも設定clipsToBounds
してくださいYES
)。さらに良いことに、ダウンロード後に実際に画像のサイズを変更できます。UIImageView
個人的な意見ですが、セルに固定サイズの を用意して、非同期の画像ダウンロードが終わったら のimage
プロパティを設定するだけで良いUXだと思いますUIImageView
。画像がダウンロードされたときに画像が UI に適切に表示されるようにする必要がありますが、通常、ユーザーが既にそこにあるものを読んでいる最中に、ビューの不快な再レイアウトが行われることは望ましくありません。デザインでセルの再レイアウトが絶対に必要な場合は、 を呼び出すだけreloadRowsAtIndexPaths
です。
で画像を遅延読み込みする一般的な方法はUITableViewCell
、通知コールバックを使用してUITableViewCell
、画像が受信されたことを通知することです。
本質的にはUIImageView
、変更されたときに画像のリクエストを実行するimageURLフィールドを持つサブクラスを作成し、標準の代わりにそれを使用する必要がありますUIImageView
。
UIImageViewサブクラスのインターフェース:
@property (nonatomic, copy) NSString *imageURL;
UIImageViewサブクラスの実装:
//synthesize property
@synthesize imageURL = _imageURL;
- (void)setImageURL:(NSString *)imageURL {
if(_imageURL)
[[NSNotificationCenter defaultCenter] removeObserver:self name:_imageURL object:nil];
_imageURL = [imageURL copy];
//if imageURL is valid...
if(_imageURL.length) {
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didReceiveImage:) name:_imageURL object:nil];
//fire off some asynchronous image fetch
//when the image fetch completes, sent off a notification using the imageURL as the notification name
//It's up to you to create the implementation for this yourself
... [MyImageManager fetchImage:_imageURL notificationName:_imageURL];
}
}
- (void)didReceiveImage:(NSNotification*)notification
{
//handle your received image here
if([notification.object isKindOfClass:[UIImage class]])
{
self.myCustomImageView.image = notification.object;
}
}
そして、prepareForReuseをオーバーライドするときのUITableViewCellクラスで:
- (void)prepareForReuse {
[super prepareForReuse];
self.myCustomImageView.imageURL = nil;
self.myCustomImageView.image = nil;
//do the rest of your prepareForReuse here:
...
}
ここで、画像の全体的なサイズ変更とimageviewのサイズ変更に関しては、imageViewのサイズをそのままにして、contentMode
プロパティを使用して結果の画像のさまざまなサイズを処理する必要があります。可能な値は次のとおりです。
UIViewContentModeScaleToFill,
UIViewContentModeScaleAspectFit,
UIViewContentModeScaleAspectFill,
UIViewContentModeRedraw,
UIViewContentModeCenter,
UIViewContentModeTop,
UIViewContentModeBottom,
UIViewContentModeLeft,
UIViewContentModeRight,
UIViewContentModeTopLeft,
UIViewContentModeTopRight,
UIViewContentModeBottomLeft,
UIViewContentModeBottomRight,
それぞれに独自の結果があります。これによりUIViewContentModeScaleAspectFit
、画像を歪ませることなく、imageViewに合わせてサイズを変更できるため、使用することをお勧めします。これにより、imageViewのサイズまたは上下に空の余白が残る場合があります。アスペクトフィルも同様のことを行いますが、画像のサイズを変更してimageView全体を塗りつぶすのに十分な大きさにし、画像の側面または上下を切り取る場合があります。塗りつぶしに拡大縮小すると、画像が引き伸ばされてimageViewが塗りつぶされます。