-1

「アイテム」オブジェクトのリストを表示する UITableView を持つコントローラーがあります。アイテムは小切手帳のエントリのようなものです。ソート以外はすべて正常に動作しているようです。以下に私が探しているソートについて説明しますが、現在、レコードは作成された順序で表示されています。Item オブジェクト (NSManagedObjects) には、日付 (NSDate)、金額 (NSDecimalNumber)、およびエントリ (エントリはアイテムとの関係である NSManaged オブジェクト) を含むプロパティがあります。

アプリケーションで、タイプ (NSNumber 0 == クレジット、1 = デビット)、タイトル、説明などのエントリを作成します。次に、金額、日付などを持つ 1 つ以上のアイテム オブジェクトを追加します。

同じ日付を共有するすべてのアイテムが同じセクションに表示されるように、アイテムをテーブル ビュー セクションで日付別にグループ化したいと考えています。各セクション内で、最初にタイプ別 (最初に貸方、次に借方)、次に金額の降順で並べ替える必要があります。セクション内のこのようなもの:

2012 年 7 月 3 日

  • クレジット: 900
  • 借方: (25)
  • 借方: (15)

2012 年 8 月 7 日

  • クレジット: 1000
  • クレジット: 900
  • クレジット: 100
  • クレジット: 25
  • 借方: (700)
  • 借方: (450)
  • 借方: (25)

ViewController 自体は、UITableViewDelegate、UITableViewDataSource、および NSFetchedResultsControllerDelegate です。

NSFetchedResultsController getter メソッドは次のとおりです。

- (NSFetchedResultsController *)aFetchedResultsController {

    if (_aFetchedResultsController != nil) {
        return _aFetchedResultsController;
    }

    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(date >= %@) AND (date <= %@)", startDate, endDate];
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Item" inManagedObjectContext:self.context];
    [fetchRequest setEntity:entity];
    [fetchRequest setPredicate:predicate];

    NSSortDescriptor *sortDate = [[NSSortDescriptor alloc] initWithKey:@"date" ascending:YES];
    NSSortDescriptor *sortType = [[NSSortDescriptor alloc] initWithKey:@"entry.type" ascending:YES];
    NSSortDescriptor *sortAmount = [[NSSortDescriptor alloc] initWithKey:@"amount" ascending:NO];
    [fetchRequest setSortDescriptors:[NSArray arrayWithObjects:sortDate, sortType, sortAmount, nil]];


    [fetchRequest setFetchBatchSize:20];

    NSFetchedResultsController *theFetchedResultsController =
    [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
                                        managedObjectContext:self.context sectionNameKeyPath:@"day"
                                                   cacheName:@"Root"];
    self.aFetchedResultsController = theFetchedResultsController;
    _aFetchedResultsController.delegate = self;

    return _aFetchedResultsController;

}//end 

読み込まれたビュー:

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view from its nib.

    NSDate *today = [NSDate new];
    NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
    NSDateComponents *offsetComponents = [[NSDateComponents alloc] init];

    [offsetComponents setMonth:-1]; //1 month ago
    startDate = [gregorian dateByAddingComponents:offsetComponents toDate:today options:0];

    [offsetComponents setMonth:1]; //1 month ahead
    endDate = [gregorian dateByAddingComponents:offsetComponents toDate:today options:0];



    //set the MOC
    self.context = [((AppDelegate *)[[UIApplication sharedApplication] delegate]) managedObjectContext];

    [self fetchRecords];

}//end viewDidLoad

そして、実際にレコードをフェッチするメソッド:

-(void)fetchRecords{

    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(date >= %@) AND (date <= %@)", startDate, endDate];
    [[self.aFetchedResultsController fetchRequest] setPredicate:predicate];
    [NSFetchedResultsController deleteCacheWithName:@"Root"];

    NSError *error;
    if (![[self aFetchedResultsController] performFetch:&error]) {

        // Update to handle the error appropriately.
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        exit(-1);  // Fail

    }//end if


    [_tableView reloadData];

}//end fetchRecords

「day」は、UITableView セクション ヘッダーに書式設定された日付文字列を表示するために使用している Item インスタンス メソッドです。

- (NSString *)day {
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    dateFormatter.dateStyle = NSDateFormatterFullStyle;

    return [dateFormatter stringFromDate:self.date];

}//end day
4

2 に答える 2

0

のドキュメントからinitWithFetchRequest:managedObjectContext:sectionNameKeyPath:cacheName:

sectionNameKeyPath

... このキー パスが fetchRequest の最初の並べ替え記述子によって指定されたものと同じでない場合、それらは同じ相対順序付けを生成する必要があります。

これはあなたのコードには当てはまりません。日付を文字列に変換しても、順序は保持されません。

Apple Developer Library には、正しく実行する方法を示すサンプル コードDateSectionTitlesがあります。

于 2012-08-07T22:24:07.633 に答える