私の甘いアプリでは、アイテムのリストから 2 種類のアイテムを使用できます。装備アイテムとバッグアイテムがあります。インベントリ画面に移動すると、テーブル ビューに 2 つのセクションがあり、それぞれに 4 つのセルがあります。装備しているアイテム用の 4 つのセルと、「バッグ」内のアイテム用の 4 つのセル。何も装備していない場合、セルは「空」と表示されます。
結果オブジェクトの形状に基づいて条件付きで表のセルに値を入力するにはどうすればよいですか?
これが私が欲しいコードです:
- (UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath {
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
// this returns 'nil' if the index path was out of bounds
NSManagedObject * item = [self.fetchedResultsController carefullyGetObjectAtIndexPath:indexPath];
if (nil == item) {
cell.textLabel.text = @"empty";
} else {
cell.textLabel.text = [item valueForKey:@"name"];
}
}
この「慎重な」objectAtIndexPath を実装しようとして遭遇したいくつかの問題:
境界チェックを試みましたが、fetchedArray がフラットであるのに対し、ナビゲートしようとしている概念モデルがフラットではないため、問題が発生しています。行は「セクション内」にあります。
try/catch を使用してみましたが、範囲外の要素は nil ではなく未定義であることを思い出しました...そのため、キャッチして反応できるエラーが発生することもあれば、ランダムな興味深いものを取得することもあります. 私が今持っているセットアップ:
@try {
NSManagedObject *managedObject = [self.fetchedResultsController objectAtIndexPath:indexPath];
return managedObject;
}
@catch (NSException * e) {
return nil;
}
一貫して私に5つのエントリを与え、4つは適切な場所に、1つのオッドボールは他のセクションからの繰り返しです.
取得した結果を手動でナビゲートする方法がわかりません。各種類 2 つずつ、合計 4 つのアイテムで遊んでいます。セクションが外側に、行が内側にある、二重にネストされた配列と同じくらい簡単だと思っていましたが、これよりも難しいようです。fetchedResults NSArray を調べると、フラットであることがわかります。すべての「バッグ」アイテムが最初にあり、「装備可能」アイテムが次に来ます。ただし、この順序付けに依存できるとは思えないため、indexPath セクションから配列インデックスに移動するマッピング関数を安全に作成できるとは思いません。(これについては安心できると確信できました)。
私が考えた代替手段は、セクションが完全に満たされない場合にプレースホルダーの結果として返される 8 つの「空の」アイテムをインベントリに入力することです。しかし、これは私にはうまくいきません。
これが機能しない理由はわかります。テーブルには「空の」行があるはずがありません。しかし、テーブルに空の行が必要です!
アップデート
これが私が現在使用している方法です...
- (NSManagedObject*) carefullyGetObjectAtIndexPath:(NSIndexPath*)indexPath
{
NSLog(@"in %@ %s", [self class], _cmd);
NSString * desiredType = (indexPath.section == BAG_SECTION)? @"bag" : @"equipable";
NSArray * fetchedObjects = [self.fetchedResultsController fetchedObjects];
NSInteger sectionStartIndex = -1;
// iterate until you hit a type you like
NSUInteger i, count = [fetchedObjects count];
for (i = 0; i < count; i++) {
NSObject * obj = [fetchedObjects objectAtIndex:i];
NSString * fetchedType = (NSString*)[obj valueForKey:@"type"];
if ([desiredType isEqualToString:fetchedType]) {
sectionStartIndex = i;
break;
}
}
if (-1 == sectionStartIndex) {
// maybe there aren't any of that type of item
} else {
NSInteger calculatedEntityIndex = sectionStartIndex + indexPath.row;
NSLog(@"calculated index %d", calculatedEntityIndex);
// if we are still in the array
if (calculatedEntityIndex < [fetchedObjects count]) {
// then we can get the object
NSManagedObject * entity = [fetchedObjects objectAtIndex:calculatedEntityIndex];
// and if we are still in the right section
NSString * typeForEntityAtIndex = [entity valueForKey:@"type"];
if ([desiredType isEqualToString:typeForEntityAtIndex]) {
// then this is what we wanted
return entity;
}
}
}
return nil;
}
このようなことを繰り返す必要があるとは本当に思いません...
z。
完全な開示: これは期間プロジェクトですが、このプロジェクトは何らかの手段でアプリを作成することです。これには、サードパーティのライブラリ、stackoverflow での質問などが含まれます。この期間のプロジェクトの目標は、目的の c を学ぶことではなく、甘いアプリなど、より大きなものに取り組むことを経験することです。