16

こちらもご覧ください

Core Data Sort By Date By FetchedResultsController をセクションに

CoreData エンティティのオブジェクトを日付別にグループ化し、それらを使用して UITableView コントロールに複数のセクションを作成する方法はありますか?

基本的に、my_group_criteria() がすべてのテストを日ごとにグループ化する次の疑似 SQL と同等のものが必要です。

SELECT * FROM tests GROUP BY my_group_criteria(date)

例として、クエリは次の行を 3 つの個別のセクションにグループ化します。

[test1 | 2013-03-18 15.30.22]
[test2 | 2013-03-18 14.30.22]
[test3 | 2013-03-18 13.30.22]

[test4 | 2013-03-17 18.30.22]
[test5 | 2013-03-17 19.30.22]

[test6 | 2013-03-15 20.30.22]

2で既に回答されているように、NSPredicate はエンティティをグループ化するためのものではないため、これは適していない可能性があります。

これを考えると、SQL GROUP BY と同様の基準に基づいて UITableView に複数のセクションを作成するにはどうすればよいでしょうか?

可能であれば、SQL-lite データベースに直接アクセスすることは避けたいと考えています。

関連する質問 1: NSPredicate: NSDate プロパティの日によるオブジェクトのフィルタリング

関連する質問 2: NSPredicate SQL の GROUP BY に相当するもの

4

2 に答える 2

14

必要に応じて、Apple Developer Library からDateSectionTitlesサンプル プロジェクトを変更できます。

最初に、transient プロパティのアクセサー関数を変更して、sectionIdentifier年 + 月 + 日 (年 + 月のみではなく) に基づいてセクション識別子を作成する必要があります。

- (NSString *)sectionIdentifier {

    // Create and cache the section identifier on demand.

    [self willAccessValueForKey:@"sectionIdentifier"];
    NSString *tmp = [self primitiveSectionIdentifier];
    [self didAccessValueForKey:@"sectionIdentifier"];

    if (!tmp) {
        /*
         Sections are organized by month and year. Create the section identifier
         as a string representing the number (year * 10000 + month * 100 + day);
         this way they will be correctly ordered chronologically regardless of
         the actual name of the month.
         */
        NSCalendar *calendar = [NSCalendar currentCalendar];

        NSDateComponents *components = [calendar components:(NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit)
                               fromDate:[self timeStamp]];
        tmp = [NSString stringWithFormat:@"%d", [components year] * 10000 + [components month] * 100  + [components day]];
        [self setPrimitiveSectionIdentifier:tmp];
    }
    return tmp;
}

次に、titleForHeaderInSectionデリゲート メソッドを変更する必要がありますが、考え方は同じです。セクション識別子から年、月、日を抽出し、そこからヘッダー タイトル文字列を作成します。

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {

    id <NSFetchedResultsSectionInfo> theSection = [[fetchedResultsController sections] objectAtIndex:section];

    NSInteger numericSection = [[theSection name] integerValue];
    NSInteger year = numericSection / 10000;
    NSInteger month = (numericSection / 100) % 100;
    NSInteger day = numericSection % 100;

    // Create header title YYYY-MM-DD (as an example):
    NSString *titleString = [NSString stringWithFormat:@"%d-%d-%d", year, month, day];
    return titleString;
}
于 2013-02-19T12:36:49.413 に答える
0

オブジェクトの配列をオブジェクトの配列の配列にグループ化することがアイデアであると仮定すると、私がとるアプローチは次のとおりです。まず、日付の可能な値 (またはグループ化したいもの) を見つけてから、実際に並べ替えます。

NSArray *values = ...;
NSArray *sorting = [values valueForKey:@"@distinctUnionOfObject.propertyToGroupBy"];
NSUInteger sectionCount = [sorting count];
NSMutableArray *sections = [NSMutableArray arrayWithCapacity:sectionCount];
for (int i = 0; i < sectionCount; i++)
    [sections addObject:[NSMutableArray array]];

[values enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
    // Figure out the section for this object
    NSUInteger section = [sorting indexOfObject:obj.propertyToGroupBy];
    [[sections objectAtIndex:section] addObject:obj];
}];

// sections will contain as many sections as there were unique values
// each of those values is an array containing values that matched the criteria

これはおそらく最適化できますが、私の頭の上からは、法案に合っているようです.

編集: もう一度質問を行った後、propertyToGroupBy は値を正規化する必要があります。つまり、日付の時間コンポーネントを削除します。これは、グループ化が一意の値によって行われるためです (つまり、比較は isEqual に基づいています:)

于 2013-02-18T18:35:32.873 に答える