UIImageViewを含むUITableViewCellを使用して、UITableViewでスムーズスクロールの問題があります。同様の問題がStrackOverflowのいたるところに見られましたが、提案された解決策はどれも、ラグを完全に取り除くのに役立ちませんでした。
私のケースはかなり一般的です:
私は複数の最適化のヒントに従い、スクロールを最適化することに成功しました。残念ながら、それはまだ完璧ではありません。これは私のシナリオです:
もともとここで画像を取得するために新しいバックグラウンドスレッドを開始する前(ステップ1)は、バックグラウンドスレッドなしのUIImageキャッシュチェックでした。この場合、キャッシュ内に画像がある場合、その画像を即座に割り当てます。これにより、高速スクロール中に大きな遅延が生じます(画像を即座にフェッチする限り、頻繁に画像を割り当てます)。これらの行は、下記の私の例でコメントされています。
まだ2つの問題があります:
これら2つの問題に対処する方法、または私のシナリオを最適化する方法は高く評価されています
Xamarinで記述されたサンプルを考慮に入れてください。ただし、ObjectiveCで記述されたアプリでも同じ問題がある限り、Xamarinが問題の原因であるとは思いません。
TableView
に保存されている120x120の画像を1つだけBundle
に入力しようとしましたか?この方法で、問題が発生したかどうかを確認できますImage rendering
すべての画像を120x120にサイズ変更してキャッシュに保存する代わりに、すべての画像のサムネイルを作成して使用することをお勧めします。あなたは何らかの形でこれをすでに行っていますが、これを数回行っています(スクロールするたびに、またはキャッシュがいっぱいの場合)。
前回のプロジェクトでは、本の表紙付きのUICollectionView
を用意しました。ほとんどのカバーは400-800kbの大きさで、スクロール中の感じは本当に悪かった。そこで、各画像のサムネイル(サムネイルは約40〜50kb)を作成し、実際のカバーの代わりにサムネイルを使用しました。魅力的な作品!サムネイル作成機能をつけました
- (BOOL) createThumbnailForImageAtFilePath:(NSString *)sourcePath withName:(NSString *)name {
UIImage* sourceImage = [UIImage imageWithContentsOfFile:sourcePath];
if (!sourceImage) {
//...
return NO;
}
CGSize thumbnailSize = CGSizeMake(128,198);
float imgAspectRatio = sourceImage.size.height / sourceImage.size.width;
float thumbnailAspectRatio = thumbnailSize.height/thumbnailSize.width;
CGSize scaledSize = thumbnailSize;
if(imgAspectRatio >= thumbnailAspectRatio){
//image is higher than thumbnail
scaledSize.width = scaledSize.height * thumbnailSize.width / thumbnailSize.height;
}
else{
//image is broader than thumbnail
scaledSize.height = scaledSize.width * imgAspectRatio;
}
UIGraphicsBeginImageContextWithOptions( scaledSize, NO, 0.0 );
CGRect scaledImageRect = CGRectMake( 0.0, 0.0, scaledSize.width, scaledSize.height );
[sourceImage drawInRect:scaledImageRect];
UIImage* destImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
NSString* thumbnailFilePath = [[self SOMEDIRECTORY] stringByAppendingPathComponent:name];
BOOL success = [UIImageJPEGRepresentation(destImage, 0.9) writeToFile:thumbnailFilePath atomically:NO];
return success;
}
Facebookの非同期表示ライブラリを試してください。
https://github.com/facebook/AsyncDisplayKit
本当に使いやすい..彼らのガイドから: http://asyncdisplaykit.org/guide/
_imageNode = [[ASImageNode alloc] init];
_imageNode.backgroundColor = [UIColor lightGrayColor];
_imageNode.image = [UIImage imageNamed:@"hello"];
_imageNode.frame = CGRectMake(10.0f, 10.0f, 40.0f, 40.0f);
[self.view addSubview:_imageNode.view];
これは、バックグラウンドスレッドでイメージをデコードします。
XamarinでiOSライブラリを簡単に使用できるかどうかはわかりませんが、簡単な場合は試してみてください。
Paul HegartyのCoreDataTableViewControllerをサブクラス化し、CoreDataTableViewで写真のサムネイルを使用します。
講義14の FlickrFetcher and Photomania というタイトルの例を探してください。また、同じリンクでCoreDataTableViewControllerをダウンロードする必要があります。
適切なタイトルでCoreDataエンティティを作成し、必要な属性(データ変数)を定義します。写真用とサムネイル用の2つの「変形可能」属性を定義する必要があります。
次に、サムネイルをCoreDataTableViewにロードします。
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{NSArray * exceptions = [NSArray arrayWithObjects:@ "SCR"、@ "DNS"、@ "NT"、@ "ND"、@ "NH"、nil];
static NSString *CellIdentifier = @"resultsDisplayCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
MarksFromMeets *athleteMarks = [self.fetchedResultsController objectAtIndexPath:indexPath];
NSString* date = [ITrackHelperMethods dateToAbbreviatedString:athleteMarks.meetDate];
NSMutableString *title = [NSMutableString stringWithFormat:@"%@", athleteMarks.markInEvent];
NSMutableString *subTitle = [NSMutableString stringWithFormat:@"%@ - %@",date, athleteMarks.meetName];
[title replaceOccurrencesOfString:@"(null)"
withString:@""
options:0
range:NSMakeRange(0, [title length])];
// cell.imageView.image = athleteMarks.photoThumbNail; // Don't like image in front of record.
[cell.textLabel setFont:[UIFont
fontWithName:@"Helvetica Neue" size:18]];
[cell.detailTextLabel setFont:[UIFont fontWithName:@"Helvetica Neue" size:16]];
[cell.detailTextLabel setTextColor:[UIColor grayColor]];
// make selected items orange
if ([athleteMarks.eventPR integerValue] != 0
&& (![exceptions containsObject:athleteMarks.markInEvent])) {
title = [NSMutableString stringWithFormat:@"%@ (PR)",title];
[cell.textLabel setTextColor:[UIColor redColor]];
}
else if ([athleteMarks.eventSB integerValue] != 0
&& (![exceptions containsObject:athleteMarks.markInEvent])) {
title = [NSMutableString stringWithFormat:@"%@ (SB)",title];
[cell.textLabel setTextColor:[UIColor orangeColor]];
} else {
[cell.textLabel setTextColor:[UIColor grayColor]];
}
cell.textLabel.text = title;
cell.detailTextLabel.text = subTitle;
cell.indentationLevel = indentationLevelOne;
cell.indentationWidth = indentationForCell;
return cell;
}
必要に応じて、エンティティのNSManagedObjectサブクラスのカテゴリの例をお送りします。このカテゴリは、写真とサムネイルをCoreDataエンティティにロードします。初めては遅くなります。ただし、その後、ユーザーはTableViewをスムーズにスクロールできるようになり、すべての更新された結果が自動的に読み込まれます。お知らせ下さい。
素晴らしい点の1つは、CoreDataがすべてのメモリ管理を処理することです。
幸運を!
コメントするのに十分な担当者がいないので、テーブルビューのスクロールパフォーマンスに役立つ回答を次に示します。
-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
これらの2つのトリックによって、私のテーブルは本当に素晴らしいものになりました。 APIサービスから画像データを取得しています。AFNETWORKINGには素晴らしい画像ローダーがありますが、画像はバンドルに含まれているので必要ありません。
似たような問題がありましたが、スクロールがスムーズではありませんでした。内部にlabelViewsを持つ変数UIImageViewをテーブルに挿入しています。私がしたことは、estimatedHeightforRowAtIndexPathのメソッドHeightforRowAtIndexPathを変更し、スクロールがスムーズになったことです。
代わりにSDWebImage
を試すこともできます。これはxamarin component でもあり、非同期イメージダウンローダー、非同期メモリ、および自動キャッシュ有効期限処理を備えたディスクイメージキャッシュを作成します。それを使用することはおそらく、多くのハードに書かれたコードを捨てることを意味します、しかしそれはそれの価値があるかもしれません-そしてあなたのコードはずっと単純になるでしょう。 iOSでは、コントローラーのviewDidLoad内にSDWebImageManager
を設定することもできます。
- (void)viewDidLoad{
...
SDWebImageManager *manager = [SDWebImageManager sharedManager];
manager.delegate = self;
...
}
ビューコントローラーをデリゲートとして設定します。次に、次のデリゲートメソッドが呼び出されたとき:
- (UIImage *)imageManager:(SDWebImageManager *)imageManager transformDownloadedImage:(UIImage *)image withURL:(NSURL *)imageURL
キャッシュする前に、画像を適切なサイズのつまみに拡大縮小できます。
お役に立てば幸いです。