19

ある種のセグメント化されたコントロールによって、NSFetchControllerの並べ替えをオンザフライで変更しようとしています。A-> ZZ->Aタイプのものをソートします。

これを行うには何をする必要がありますか?私はここでジェフ・ラマルシェの例に従っています:ここに

新しいNSFetchedResultsControllerを作成してから設定する必要がありますか、それとも単に新しいNSFetchRequestを作成して実行する必要がありますか?

fetchedResultController.fetchRequest = newFetchRequest

その後、私のテーブルは自動的に更新されますか?

4

4 に答える 4

33

私は同じ問題に悩まされていました.FetchRequestControllerのFetchRequestにソート記述子を設定してから、フェッチを実行し(performFetch)、最後にテーブルビューにデータをリロードするだけで修正できました.

NSArray *sortDescriptors = [NSArray arrayWithObject: sorter];
[[fetchedResultsController fetchRequest] setSortDescriptors:sortDescriptors];
NSError *error;
if (![[self fetchedResultsController] performFetch:&error]) {
        // Handle you error here
}
[sorter release];
[myTableView reloadData];

これは、FRC を削除したり、他の手の込んだオブジェクト処理を行ったりすることなく、オンザフライで並べ替えの変更に対処する最も簡単な方法でした。それに対するパフォーマンスへの影響についてはわかりません。テーブル内の行のセットが巨大な場合、影響がある可能性があります。

于 2010-09-12T18:53:19.120 に答える
7

NSFetchedResultsController をテーブル ビューのデータ ソースとして使用する代わりに、フェッチされた結果に基づく配列の内容に基づいてセグメント化されたコントロールでユーザーが並べ替え順序を変更したときに設定する NSArray を作成します。次に、標準の配列ソートを使用してソートします。このようなもの:

- (IBAction)segmentChanged:(id)sender
{
    // Determine which segment is selected and then set this 
    // variable accordingly
    BOOL ascending = ([sender selectedSegmentIndex] == 0);

    NSArray *allObjects = [fetchedResultsController fetchedObjects];

    NSSortDescriptor *sortNameDescriptor = 
                       [[[NSSortDescriptor alloc] initWithKey:@"name" 
                                 ascending:ascending] autorelease];

    NSArray *sortDescriptors = [[[NSArray alloc] 
                     initWithObjects:sortNameDescriptor, nil] autorelease];

    // items is a synthesized ivar that we use as the table view
    // data source.
    [self setItems:[allObjects sortedArrayUsingDescriptors:sortDescriptors]];

    // Tell the tableview to reload.
    [itemsTableView reloadData];    
}

したがって、私が使用したソート記述子は「名前」と呼ばれますが、これを取得した結果でソートするフィールドの名前に変更します。また、私が参照した項目 ivar は、新しいテーブル ビュー データ ソースになります。テーブル ビューのデリゲートは次のようになります。

- (NSInteger)tableView:(UITableView*)tableView 
 numberOfRowsInSection:(NSInteger)section
{
    return [items count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView
         cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Get your table cell by reuse identifier as usual and then grab one of
    // your records based on the index path
    // ...

    MyManagedObject *object = [items objectAtIndex:[indexPath row]];

    // Set your cell label text or whatever you want 
    // with one of the managed object's fields.
    // ...

    return cell;
}

これが最善の方法かどうかはわかりませんが、うまくいくはずです。

于 2009-11-11T22:51:15.460 に答える
1

fetchRequest読み取り専用プロパティです。投稿のコード行は機能しません。別のフェッチ リクエストを使用する場合は、コントローラを新しい に置き換える必要がありますNSFetchedResultsController。テーブルは自動的にリロードされません。reloadDataを交換した後、しばらくしてからメッセージを送信する必要がありますNSFetchedResultsController

于 2009-11-11T20:18:59.383 に答える