Estoy tratando de usar un FRC con datos de lenguaje mixto y quiero tener un índice de sección.NSFetchedResultsController v.s. UILocalizedIndexedCollation
Parece que a partir de la documentación que debe ser capaz de anular el
- (NSString *)sectionIndexTitleForSectionName:(NSString *)sectionName
- (NSArray *)sectionIndexTitles
y de FRC continuación, utilizar el UILocalizedIndexedCollation tener un índice y secciones localizadas. Pero lamentablemente esto no funciona y no es lo que se pretende utilizar :(
¿Alguien ha podido usar un FRC con UILocalizedIndexedCollation o estamos obligados a utilizar el método de clasificación manual mencionado en el ejemplo ejemplo UITableView + UILocalizedIndexedCollation (código de ejemplo incluido en tengo este trabajo)
Usando las siguientes propiedades
@property (nonatomic, assign) UILocalizedIndexedCollation *collation;
@property (nonatomic, assign) NSMutableArray *collatedSections;
y el código:.
- (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];
}
Me encantaría poder utilizar el protocolo FRCDelegate para recibir notificaciones de actualizaciones. Parece que no hay una buena manera de hacer que estos dos objetos funcionen juntos muy bien.
Tendré que probar esto la próxima vez que se me presente este problema (la solución existente funciona bien). Solo una nota: nunca se debe usar localizedCaseInsensitiveCompare porque algunos idiomas (como el francés, creo) tienen en cuenta el caso al ordenar; use localizedStandardCompare. Esto fue mencionado en el último video localizador WWDC –
De todas las soluciones que he encontrado para ordenar y mostrar datos indexados de un FRC, esta es la más elegante. ¿Has encontrado una forma de mover la sección # hasta el final? Siento que una de las opciones de clasificación de cadenas haría esto y es extraño que sectionIndexTitles de UILocalizedIndexedCollation se ordene de manera diferente al orden que los comparadores de cadenas clasifican. –
Esto no es una bala de plata, así que ten cuidado. Como se observa en otra respuesta, no se puede construir una 'NSFetchRequest' con una clasificación en una propiedad transitoria como la que ha descrito. (Al menos, no si está usando un almacén de datos Core respaldado por SQLite). Por lo tanto, si su orden de clasificación es diferente del orden de la intercalación, el 'NSFetchedResultsController' generará un error y no devolverá ninguna fila. Por ejemplo, si el apellido de un usuario comienza con una letra minúscula, se ordenará * después de * todos los demás nombres, pero la intercalación tratará de ponerlo con otros nombres que comiencen con la misma letra (pero en mayúscula). – jsadler