1

大きな行セットのテーブル ビュー セクションを手動で計算することについて、Apple 開発フォーラムで興味深い議論が行われています。表示するには、開発者アカウントが必要です。

NSFetchedResultsController が DB 内のすべてのオブジェクトを取得しています...

開発者アカウントを持っていない人のために、Apple の技術者は、インデックス タイトルを含むエンティティを使用し、行に表示するエンティティとの対多関係を使用することを提案しています。

典型的な例は、インデックス セクションのタイトルが最初の文字 A、B、C である曲またはアーティストのコレクションです。

したがって、タイトル A のエンティティは、文字 A で始まる曲と対多の関係を持つことになります。

このメカニズムは、フェッチされた結果コントローラーを使用してすべての曲を取得すると同時に、インデックスの NSArray を取得するためのフェッチ要求を開始します。

NSFetchRequest *req = //fetch request for section entity
NSArray *sections = [MOC executeFetchRequest:req error:&error];

セクション数とセクション内の行を取得するのは非常に簡単です。

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    // Return the number of sections.
    NSInteger abc = [self.sections count];
    return abc;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    CardSection *s = (CardSection*)[self.sections objectAtIndex:section];
    NSInteger rows = [s.cards count];
    return rows;
}

-(NSString*)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
    CardSection *s = [self.sections objectAtIndex:section];
    NSString *title = s.title;
    return title;
}

ただし、問題はインデックス パスの行のセルで始まります。

- (UITableViewCell *)tableView:(UITableView *)table cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    NSManagedObject obj = [_fetchedResultsController objectAtIndexPath:indexPath];
    // build cell....    
    return cell;
}

明らかに、インデックス パスは計算されたセクションと行を参照しているため、フェッチされたコントローラーは範囲外になります。

もちろん、これはセクション エンティティを呼び出して NSSet 関係で特定のインデックス オブジェクトを要求することで解決できますが、この方法ではフェッチされたコントローラーを持つ利点が失われます。

誰かがこのアプローチを試みたのだろうか、そして彼はどうやって問題を解決したのだろうか.

4

1 に答える 1

0

これまでに見つけた唯一の解決策は、セクション配列を解析して、特定のインデックスで先行するオブジェクトの量を見つけることです。

        int latestCount=0;
        // BOX_INT is just a personal macro for converting something to NSNumber
        self.totalAtIndex=[NSMutableDictionary dictionaryWithCapacity:0];
        [self.totalAtIndex setObject:BOX_INT(0) forKey:BOX_INT(0)];
        for (int i=1;i<[self.sections count];i++) {
            CardSection *cardSection = [self.sections objectAtIndex:i-1];
            latestCount = latestCount + [cardSection.cards count];
            [self.totalAtIndex setObject:BOX_INT(latestCount) forKey:BOX_INT(i)];
        }

たとえば、これが [a,b] が単なる NSIndexPath である私のセクションであるとします。

[0,0][0,1] (2 objects)
[1,0]      (1 object)
[2,0][2,1] (2 object)

インデックス 2 の場合、[self.totalAtIndex objectAtIndex:2]には、以前にインデックス 0 + インデックス 1 に格納されたオブジェクトの量が含まれるため、3 が返されます。インデックス [2,1] は [0,5 に変換されます。 ]。

そして、これは対応する cellForRow:atIndexPath:

- (UITableViewCell *)tableView:(UITableView *)table cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    // hack index path
    NSInteger section = indexPath.section;
    NSInteger row = indexPath.row;

    int howManyBefore = [[self.totalAtIndex objectForKey:BOX_INT(section)] intValue];
    NSIndexPath *newIndexPath = [NSIndexPath indexPathForRow:row+howManyBefore inSection:0];

    NSManagedObject *obj = [_fetchedResultsController objectAtIndexPath:newIndexPath];

    // build and return cell

}

誰かがより良い解決策を持っていれば...

于 2012-10-12T08:07:27.900 に答える