2012-10-09 40 views
4

我想提出一個通訊錄應用,在那裏,我從通訊錄取名字,並將它們存儲在覈心數據,並利用NSFetchedResultsController.However,來了就是#後面的字母第一指標和部分表中顯示的名稱。但我想要這樣做,就像在本地聯繫人應用程序中那樣,即#索引應該最後到來。
我用下面NSortDescriptorNSSortDescriptor問題

sortDescriptor = [[NSSortDescriptor的alloc] initWithKey:@ 「全名」 升序:YES];

這裏「fullName」是核心數據中的key,它是通過連接名字和姓氏。 而區間確定爲「全名」如果fullName不以字母開頭,其區間確定爲#的第一個字母。
我搜索了一下,並在NSortDescriptor比較使用NSDiacriticInsensitiveSearch但它並沒有奏效。如果任何人有任何想法,然後讓我知道。

這裏去我的代碼:

NSString *special = @"\uE000"; 
if ([[self sectionName:contactName] isEqualToString:@"#"]) {       
    sortName = [special stringByAppendingString:contactName]; 
} 
else{ 
    sortName = contactName; 
} 
[newContact setValue:[self sectionIdentifier:sortName] forKey:@"sectionIdentifier"]; 
[newContact setValue:sortName forKey:@"sortName"]; 

這裏是那種描述:

sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"sortName" ascending:YES]; 

[self sectionIdentifier:sortName]此方法將返回#如果sortName使用非字母開始,否則返回字母表由開始。

newContact是實體的對象。

回答

6

如果名稱以字母開頭,你可以存儲在實體,這是fullName附加屬性sortName,並<C>fullName否則。 <C>是比所有字母「更大」的固定字符。例如

NSString *special = @"\uE000"; 
if ("fullName starts with letter") 
    sortName = fullName; 
else 
    sortName = [special stringByAppendingString:fullName]; 

現在,您可以根據sortName排序,以及區間確定將「#」如果sortName開始與特殊字符。

的缺點是,你必須存儲額外的屬性,其優點是可以繼續使用讀取的結果控制器(其可以僅使用持久屬性進行排序)。

UPDATE:它實際上可以做更容易一點。

當您創建一個新條目,設置sectionIdentifier的名稱的第一個字符,如果它是一個字母,以及特殊字符,否則:

NSString *special = @"\uE000"; 

if ([[NSCharacterSet letterCharacterSet] characterIsMember:[contact.contactName characterAtIndex:0]]) { 
    contact.sectionIdentifier = [contact.contactName substringToIndex:1]; 
} else { 
    contact.sectionIdentifier = special; 
} 

獲取的成果控制器使用sectionIdentifier的分組和整理部分。每個部分中的條目由contactName排序:現在

NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Contact"]; 
NSSortDescriptor *sort1 = [NSSortDescriptor sortDescriptorWithKey:@"sectionIdentifier" 
      ascending:YES selector:@selector(localizedStandardCompare:)]; 
NSSortDescriptor *sort2 = [NSSortDescriptor sortDescriptorWithKey:@"contactName" 
      ascending:YES selector:@selector(localizedStandardCompare:)]; 
[request setSortDescriptors:@[sort1, sort2]]; 
self.frc = [[NSFetchedResultsController alloc] initWithFetchRequest:request 
        managedObjectContext:self.context 
        sectionNameKeyPath:@"sectionIdentifier" 
           cacheName:nil]; 

所有非字母的條目在最後一節編組。最後一步就是以顯示正確的節頭#最後一節:

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section { 
    id <NSFetchedResultsSectionInfo> sectionInfo = [[self.frc sections] objectAtIndex:section]; 
    NSString *title = [sectionInfo name]; 
    if ([title isEqualToString:special]) 
     title = @"#"; 
    return title; 
} 
+0

我試過你的方法,但它不返回正確的部分名稱和索引 – user1632153

+0

@ user1632153:你可以把你的代碼(或減少示例項目)在哪裏我可以下載它?我會試圖找出解決辦法。 –

+0

我已添加我的代碼 – user1632153

1

你可以這樣做:

sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"fullName" ascending:YES selector:@selector(localizedCaseInsensitiveCompare:)]; 

只要確保它不會在你的情況會影響性能。

+0

我已經試過這一點,它不工作。 –

0

你可以嘗試編寫自己的比較功能

假設它是排序ManagedObjects,他們都有全名作爲一個字段,那麼下面可能會有幫助。

[[NSSortDescriptor alloc] initWithKey:@"FullName" ascending:YES comparator:^NSComparisonResult(id obj1, id obj2) { 
     return [[obj1 objectForKey:@"fullName"] compare:[obj2 objectForKey:@"fullName"] options:NSCaseInsensitiveSearch]; 
    }]; 

這樣做的好處是你也可以爲每個比較編寫NSLog,看看發生了什麼。

+0

應用程序崩潰通過使用此 – user1632153

+2

這來在調試器:不支持NSSortDescriptor(比較塊不支持) – user1632153

2

您可以將結果拆分爲兩個數組,一個以alpha字符開頭,另一個不是。然後只需將兩者加在一起。假設你開始與管理對象的數組稱爲results

//Create the sort descriptor array 
NSSortDescriptor *sd = [NSSortDescriptor sortDescriptorWithKey:@"fullName" ascending:YES]; 
NSArray *descriptors = [NSArray arrayWithObject:sd]; 

//Create a sorted array of objects where fullName starts with an alpha character 
//using a Regex 

NSPredicate *pred = [NSPredicate predicateWithFormat:@"fullName MATCHES '^[a-zA-Z].*'"]; 

NSArray *alpha = [[results filteredArrayUsingPredicate:pred] sortedArrayUsingDescriptors:descriptors]; 

//Now use the alpha array to create an array of objects where the fullName does not 
//start with an alpha character 

NSMutableArray *nonAlpha = [results mutableCopy]; 

[nonAlpha removeObjectsInArray:alpha]; 

[nonAlpha sortUsingDescriptors:descriptors]; 

//Now put them back together again 

NSArray *sortedResults = [alpha arrayByAddingObjectsFromArray:nonAlpha]; 

//And if you're not using ARC! 
[nonAlpha release];