14

混合言語データで FRC を使用しようとしていますが、セクション インデックスが必要です。

ドキュメントから、FRCをオーバーライドできるはずのようです

- (NSString *)sectionIndexTitleForSectionName:(NSString *)sectionName
- (NSArray *)sectionIndexTitles

次に、UILocalizedIndexedCollat​​ion を使用してローカライズされたインデックスとセクションを作成します。しかし悲しいことに、これは機能せず、使用することを意図したものではありません:(

UILocalizedIndexedCollat​​ion で FRC を使用できた人はいますか、それとも UITableView + UILocalizedIndexedCollat​​ion の例 (これを機能させた場所にコードが含まれています) に記載されている手動の並べ替え方法を使用することを余儀なくされていますか?

次のプロパティの使用

@property (nonatomic, assign) UILocalizedIndexedCollation *collation;
@property (nonatomic, assign) NSMutableArray *collatedSections;

そしてコード:

- (UILocalizedIndexedCollation *)collation
{
    if(collation == nil)
    {
        collation = [UILocalizedIndexedCollation currentCollation];
    }

    return collation;
}

- (NSArray *)collatedSections
{
    if(_collatedSections == nil)
    {
        int sectionTitlesCount = [[self.collation sectionTitles] count];

        NSMutableArray *newSectionsArray = [[NSMutableArray alloc] initWithCapacity:sectionTitlesCount];
        collatedSections = newSectionsArray;
        NSMutableArray *sectionsCArray[sectionTitlesCount];

        // Set up the sections array: elements are mutable arrays that will contain the time zones for that section.
        for(int index = 0; index < sectionTitlesCount; index++) 
        {
            NSMutableArray *array = [[NSMutableArray alloc] init];
            [newSectionsArray addObject:array];
            sectionsCArray[index] = array;
            [array release];
        }


        for(NSManagedObject *call in self.fetchedResultsController.fetchedObjects)
        {
            int section = [collation sectionForObject:call collationStringSelector:NSSelectorFromString(name)];
            [sectionsCArray[section] addObject:call];
        }

        NSArray *sortDescriptors = self.fetchedResultsController.fetchRequest.sortDescriptors;
        for(int index = 0; index < sectionTitlesCount; index++) 
        {
            [newSectionsArray replaceObjectAtIndex:index withObject:[sectionsCArray[index] sortedArrayUsingDescriptors:sortDescriptors]];
        }
    }
    return [[collatedSections retain] autorelease];
}

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 
{
    // The number of sections is the same as the number of titles in the collation.
    return [[self.collation sectionTitles] count];
}


- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 
{
    // The number of time zones in the section is the count of the array associated with the section in the sections array.
    return [[self.collatedSections objectAtIndex:section] count];
}


- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section 
{
    if([[self.collatedSections objectAtIndex:section] count])
        return [[self.collation sectionTitles] objectAtIndex:section];
    return nil;
}


- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView {
    return [self.collation sectionIndexTitles];
}


- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index {
    return [self.collation sectionForSectionIndexTitleAtIndex:index];
}

FRCDelegate プロトコルを使用して、更新の通知を受け取ることができるようにしたいと考えています。この 2 つのオブジェクトをうまく連携させる良い方法はないようです。

4

4 に答える 4

6

一時的なプロパティで並べ替えることができないため、私が実装した解決策は...

  1. Core Data モデルの各エンティティ内の並べ替え可能な属性ごとに、「sectionKey」という文字列属性を作成します。sectionKey 属性は、ベース属性 (名前やタイトル属性など) から計算された値になります。(現在) フェッチ要求のソート記述子で一時プロパティを使用できないため、永続化する必要があります。並べ替えが提供される各 sectionKey および base 属性のインデックス作成を有効にします。この更新プログラムを既存のアプリに適用するには、軽量の移行を実行し、既存のデータベースを更新するルーチンも含める必要があります。

  2. データをシードしている場合 (たとえば、新しいインストールに標準のデータ セットを入力したり、ターゲット言語ごとにローカライズされた SQLite データベースを作成したりして、そのうちの 1 つが最初の起動時にコピーされる)、そのコードでそれぞれを計算して更新します。エンティティの sectionKey 属性。データをシードするための「最良の」アプローチについては意見が分かれていますが、言語ごとに少数の plist ファイル (数百の値で構成されるリストの場合でも、通常は数バイトから 20k の範囲) が残ることに注意してください。各言語の個々の SQLite データベース (それぞれ約 20k から開始) よりも全体的なフットプリントがはるかに小さくなります。ちなみに、Microsoft Excel for Mac は、言語機能を有効にすることで、ローカライズされたリストの並べ替えを提供するように構成できます (3)。

  3. フェッチされた結果のコントローラー コンストラクターで、sectionKey と base 属性で並べ替え、セクション名キー パスの sectionKey を渡します。

  4. 計算ロジックを追加して、すべての追加または編集ユーザー入力 (たとえば、textFieldDidEndEditing:) で sectionKey 属性を更新します。

それでおしまい!フェッチされたオブジェクトを配列の配列に手動で分割する必要はありません。NSFetchedResultsController は、ローカライズされた照合を行います。たとえば、中国語 (簡体字) の場合、フェッチされたオブジェクトは音声発音 (4) によって索引付けされます。

(1) Apple IOS Developer Library > Internationalization Programming Topics > Internationalization and Localization から。(2) TableViewSuite の3_SimpleIndexedTableView。(3) Microsoft Office for Mac で中国語機能を有効にする方法。(4) 中国語は通常、画数または音声発音のいずれかで分類されます。

于 2012-11-08T16:03:24.547 に答える
3

ブレント、私のソリューションは FRC に基づいており、オブジェクトのセクション名を返すモデル オブジェクトの一時的な属性を指定して、フェッチからセクション化を取得します。私は UIlocalizedIndexedCollat​​ion を属性ゲッターの実装でのみ使用し、テーブル ビュー コントローラーの FRC 実装に依存しています。もちろん、フェッチのソート セレクターとして localizedCaseInsensitiveCompare を使用します。

- (NSString *)sectionInitial {

    NSInteger idx = [[UILocalizedIndexedCollation currentCollation] sectionForObject:self     collationStringSelector:@selector(localeName)];
    NSString *collRet = [[[UILocalizedIndexedCollation currentCollation] sectionTitles]     objectAtIndex:idx];

    return collRet;
}

私が持っている唯一の欠点は、DB からの並べ替えを変更しないため、最後に # セクションを含めることができないことです。他のすべてはうまくいきます。

于 2012-02-16T17:38:51.677 に答える