1

私は次のようなCoreDataモデルを持っています:

国<---->>>都市(1対多の関係)

セクション/行構造としてUITableViewにリストされます。

===エジプト ===
カイロ
アレクサンドリア
LuxurRasAlBar
。 。 ===カタール=== ドーハ 。 。 。









これで、UISearchBarができました。これにより、ユーザーは、国名または都市名の両方に入力された単語の存在に基づいてTableViewをフィルタリングできます。

そのため、ユーザーが「ar」を挿入すると、次のように表示されます。

===エジプト===
ラスアルバー
===カタール===
ドーハ




CoreDataで目的を達成するための最適なクエリが見つかりません。

4

1 に答える 1

2

これには を使用する必要がありますNSFetchedResultsController。あなたがそうであるかどうかは言及していませんがCoreDataTableView.

とにかく、あなたのフェッチNSFetchedResultsControllerは都市にあるべきです。国ではありません。(繰り返しますが、念のためにそれがどれであるかは言いません)。

したがって、使用できる述語は...

NSPredicate *cityPredicate = [NSPredicate predicateWithFormat:@"name [cd]CONTAINS %@", text];
NSPredicate *countryPredicate = [NSPredicate predicateWithFormat:@"country.name [cd]CONTAINS %@", text];

NSPredicate *compoundPredicate = [NSCompoundPredicate orPredicateWithSubPredicates:@[cityPredicate, countryPredicate]];

次にcompoundPredicate、フェッチに を使用すると、探しているものが得られます。

NSFetchedResultsController のセットアップ方法

CountryTableViewController.mファイル

1 - プロパティを作成...

@property (nonatomic, strong) NSFetchedResultsController *fetchedResultsController;
@property (nonatomic, strong) NSManagedObjectContext *managedObjectContext;

2 - ソースから管理オブジェクト コンテキストを取得します...

self.managedObjectContext = [(AppDelegate*)[[UIApplication sharedApplication] delegate] managedObjectContext];

3 - このメソッドを追加...

#pragma mark - fetched results controller

- (NSFetchedResultsController*)fetchedResultsController
{
    if (_fetchedResultsController != nil) {
        return _fetchedResultsController;
    }

    NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"City"];
    [request setFetchBatchSize:20];

    NSSortDescriptor *sd = [NSSortDescriptor sortDescriptorWithKey:@"country.name" ascending:NO];

    [request setSortDescriptors:[NSArray arrayWithObject:sd]];

    NSFetchedResultsController *aController = [[NSFetchedResultsController alloc] initWithFetchRequest:request managedObjectContext:self.managedObjectContext sectionNameKeyPath:@"country.name" cacheName:nil];

    aController.delegate = self;
    self.fetchedResultsController = aController;

    NSError *error = nil;
    if (![self.fetchedResultsController performFetch:&error]) {
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        abort();
    }
    return _fetchedResultsController;
}

4 - テーブルをフィルタリングするメソッドの場合...

- (void)filterResultsWithText:(NSString*)text
{
    NSPredicate *cityPredicate = [NSPredicate predicateWithFormat:@"name [cd]CONTAINS %@", text];
    NSPredicate *countryPredicate = [NSPredicate predicateWithFormat:@"country.name [cd]CONTAINS %@", text];

    NSPredicate *compoundPredicate = [NSCompoundPredicate orPredicateWithSubPredicates:@[cityPredicate, countryPredicate]];

    [self.fetchedResultsController.fetchRequest setPredicate:compoundPredicate];

    NSError *error = nil;
    if (![self.fetchedResultsController performFetch:&error]) {
        // Handle error
        //exit(-1);
    }

    [self.tableView reloadData];
}

5 - データを表示する

これでデータが設定されます。これ以上配列は必要ありません。

それを表示するには、次のことができます...

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return [[self.fetchedResultsController sections] count];
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    id <NSFetchedResultsSectionInfo> sectionInfo = [self.fetchedResultsController sections][section];
    return [sectionInfo numberOfObjects];
}

- (NSString*)tableView:(UITableView*)tableView titleForSection:(NSInteger*)section
{
    id <NSFetchedResultsSectionInfo> sectionInfo = [self.fetchedResultsController sections][section];
    return [sectionInfo title];
}

インデックスパスで国を取得するには、これを行うことができます...

Country *country = [self.fetchedResultsController objectAtIndexPath:indexPath];

これにより、そのインデックス パスの国が返されます。

設定には少し手間がかかりますが、一度設定すると、なぜこんなに簡単なのかがわかります。

于 2013-01-29T17:24:45.453 に答える