これが問題のビデオです: http://youtu.be/Jid0PO2Hgc
アセットライブラリのUITableViewで[cell imageView]の画像を設定しようとすると問題が発生します。
画像は読み込まれますが、そのセルをタッチ(選択)するまで、セルに表示されません。セルのimageViewを設定するコードは次のとおりです。
//Start loading the image using the image path
NSString *path = [occasion imagePath];
if (path != nil && [path hasPrefix:@"ass"])
{
NSLog(@"photo loaded from assets library");
//testing ALAssestLibrary
ALAssetsLibrary* assetsLibrary = [[ALAssetsLibrary alloc] init];
ALAssetsLibraryAssetForURLResultBlock resultsBlock = ^(ALAsset *asset)
{
ALAssetRepresentation *representation = [asset defaultRepresentation];
CGImageRef imageRef = [representation fullResolutionImage];
UIImage *image = [[UIImage alloc] initWithCGImage:imageRef];
[[cell imageView] setImage:[image imageByScalingAndCroppingForSize:CGSizeMake(36.0, 42.0)]];
[image release];
};
ALAssetsLibraryAccessFailureBlock failureBlock = ^(NSError *error){
NSLog(@"FAILED! due to error in domain %@ with error code %d", error.domain, error.code);
// This sample will abort since a shipping product MUST do something besides logging a
// message. A real app needs to inform the user appropriately.
abort();
};
//Convert path to an NSUrl
NSURL *url = [NSURL URLWithString:path];
// Get the asset for the asset URL to create a screen image.
[assetsLibrary assetForURL:url resultBlock:resultsBlock failureBlock:failureBlock];
// Release the assets library now that we are done with it.
[assetsLibrary release];
}
上記のコードは次の一部です。
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
何か案は?
この場合、iOSで定義されたUITableViewCell(カスタムではない)を使用していると思います。これは、「initWithStyle:reuseIdentifier:」から取得するセルの1つです。これらのセルは、コンテンツをすぐに割り当てない場合、対応するサブビューがセルのcontentView階層に追加されないように、内部的に構築されています。この種の動作は典型的な複雑なカスタムビューであり、最終的なセルレイアウトは、そのすべてのサブビューのコンテンツが完全に指定されている場合にのみ決定できます。 (たとえば、2つのラベルがあり、たとえばラベルAとラベルBがあるとします。ラベルAは複数行であり、ラベルBをラベルAのすぐ下に追加したい場合、ラベルBはラベルAのコンテンツを取得した後でのみ正しく配置できます。そしてその高さを計算します。)したがって、組み込みのiOSテーブルセルは同じ方法で作成され、サブビュー階層は「layoutSubviews」ステージで構築されると思います。
あなたのケースでは、セルを作成しますが、画像が提供される時間を延期します。しかし、この時点で、layoutSubviewsはまだ呼び出されており、画像がないと、対応するimageViewが割り当てられず、contentView階層に追加されません。
したがって、私によると、あなたのための解決策は、アセットの「プレースホルダー」をただちに割り当てることです(プレースホルダーはもちろん透明な画像にすることもできます)。これにより、内部UIImageViewの作成が保証されます。画像サイズに注意してください。上記と同じ理由で、予想される画像サイズに近いはずです。終了ブロックが呼び出されるとすぐに、画像ビューがすでに存在しているはずであり、画像が表示されます。
セルをタップしたときに画像が表示されるのは、この操作でlayoutSubviewsが再度呼び出されるためです。この場合、コード全体がおそらく再実行され、以前に「setImage:」を呼び出したので、内部の「image」プロパティが設定され、contentView階層が新しい画像で再構築されます。
もちろん、問題の別の可能な解決策は、「カスタム」UITableViewCell(たとえば、Nibからロードされたもの)を使用することです。そのような場合、すべてのサブビューが読み込まれ、タグを使用してUIImageViewにアクセスするだけです(Apple docsを読んで、Nibファイルからテーブルビューセルを作成するこの便利な手法について詳しく知る) 。
画像セットの後にセルをレイアウトする必要があります
と同じように
[セルsetNeedsLayout];
私は長い間頭を掻き、ついにそれを理解しました。
私の間違いは、私がcell.imageView
実際のコンセントを設定する必要がある場合cell.eventImageView
。 UITableViewCell
で提供されている一般的なimageviewがめちゃくちゃでした。それが誰かを助けることを願っています。
これは私がこれらの問題をどのように解決したかという私の方法です、私は最善ではありませんが、その仕事を知っています:)
UIImage *thumbnailImage = ...
dispatch_async(dispatch_get_main_queue(), ^{
[cell.imageView setImage:thumbnailImage];
UITableViewCellSelectionStyle selectionStyle = cell.selectionStyle;
cell.selectionStyle = UITableViewCellSelectionStyleNone;
[cell setSelected:YES];
[cell setSelected:NO];
cell.selectionStyle = selectionStyle;
});
私の場合、ストーリーボードを介してプロトタイプセルをセットアップしていましたが、誤ってdequeueCellWithIdentifier:forIndexPath
ではなくdequeueCellWithIdentifier:
メソッドを使用していました。
最初の方法は、プログラムによるUITableView registerClass:forReuseIdentifier:
またはregisterNib:forReuseIdentifier
メソッドを介してセルをテーブルビューに割り当てる場合にのみ使用されます。
私は同様の問題を抱えていました。カスタムクラスではなく、デフォルトのUITableViewCellクラスを登録しました。
私はこれを持っていました:
tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: visibilityCellIdentifier)
しかし、私はこれを持っていたはずです:
tableView.registerClass(VisibilityCell.self, forCellReuseIdentifier: visibilityCellIdentifier)
デバッガーをステップ実行すると、セルの作成はすべて機能しているように見えましたが、各行を選択するまで何も表示されませんでした。
ラベルや画像などでカスタムUITableViewCell
を使用しているときだけでなく、セルのデフォルトのUILabelを設定しているときにも発生します。例えば
customCell.textLabel.text = @"some text"
この問題を解決するには、デフォルトのラベルの使用を避け、代わりにカスタムセルに独自のUILabelを追加します。
このコードを使用すると、同じ問題が発生します。
cell = [tableView dequeueReusableCellWithIdentifier:kCellSection1 forIndexPath:indexPath];
if (indexPath.row == 0) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:kCellSection1];
cell.textLabel.text = @"Vote Up for me if it help for you!";
}
しかし、私は置き換えることでそれを修正します:
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:kCellSection1];
に:
cell = [cell initWithStyle:UITableViewCellStyleDefault reuseIdentifier:kCellSection1];