1

私の甘いアプリでは、アイテムのリストから 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 を学ぶことではなく、甘いアプリなど、より大きなものに取り組むことを経験することです。

4

1 に答える 1

1

ジギー、

NSFetchedResultsControllerは多くの制限があります。スキーマをその厳密な要件を満たすことができず、おそらく満たしていないように見える場合はtableView、複数NSFetchRequestの から構成する必要があります。それは簡単です。興味深いtableViewのほとんどはまさにこれを行います。Core Data は、大規模なフェッチを実行してから、コレクション クラスで設定操作とフィルター操作を使用して検索を絞り込む場合に最適に機能します。

tableViews には空の行を含めることができます。これを、さまざまなデリゲートおよびセル構成コードのカスタム コードと調整するだけです。

問題を解決するための多くのオプションがあります。フレームワーク API が非常に限られていることに不満を感じているようです。あなたは新進のプログラマーです。自分で巻いてください。

アンドリュー

PS あなたには、Objective-C を学ばなくても Mac OS X/iOS アプリを作成するという興味深い目標があります。あなたは実際に、Objective-C を最大限に活用するフレームワークである Core Data の 1 つのテクノロジを選択しました。(私の意見では、iOS プログラマーの教育者として、ありふれた主流の SQL ソリューションに引きこもるよりも、まったく異なる永続性モデルである Core Data のモデルの複雑さを学ぶ方が、おそらくあなたの教育に役立つでしょう。)別の言語では、MacRuby/RubyMotion が非常に効果的です。

于 2012-07-01T15:03:33.660 に答える