2014-09-06 54 views
0

我需要一些幫助索引UITableView,除以字母部分的數據。數據模型來自核心數據圖。iOS索引tableview使用核心數據和排序 - 索引是好的,但數據不是

我有索引(A-Z),加載正常,節標題正確。問題是數據沒有正確排序(即字母)。

模型中有一個實體屬性是字母索引。我已經看過了sqlite文件,這沒關係。

下面是一些相關的代碼。請幫我瞭解我丟失或搞亂:)

- (void)viewDidLoad { 
    [super viewDidLoad]; 

    sectionArray = [[NSArray alloc] init]; 
    self.collation = [UILocalizedIndexedCollation currentCollation]; 

    if (languageKey == 0) { 
     sectionArray = [NSArray arrayWithArray:[@"|α,ά|β|γ|δ|ε,έ|ζ|η,ή|θ|ι,ί|κ|λ|μ|ν|Ξ|ο,ό|π|ρ|σ|τ|υ,υ|φ|χ|ψ|ω,ώ|#" 
               componentsSeparatedByString:@"|"]]; 

    } else { 
     sectionArray = [NSArray arrayWithArray: 
         [@"A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z|#" 
         componentsSeparatedByString:@"|"]]; 
    } 

    NSManagedObjectContext *context = [self managedObjectContext]; 
    NSEntityDescription *entityDescription = [NSEntityDescription 
               entityForName:@"WordEntity" inManagedObjectContext:context]; 
    NSFetchRequest *request = [[NSFetchRequest alloc] init]; 
    [request setEntity:entityDescription]; 
    [request setPredicate:[self predicate]]; 
    [request setIncludesSubentities:NO]; 

    filteredWordsArray = [[NSMutableArray alloc] init]; 
    self.searchResults = [NSMutableArray arrayWithCapacity:[[self.fetchedResultsController fetchedObjects] count]]; 

    self.searchDisplayController.searchResultsTableView.rowHeight = wordTable.rowHeight; 
} 

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 
{ 
    if (tableView == self.searchDisplayController.searchResultsTableView) 
    { 
     return [self.searchResults count]; 
    } 
    else 
    { 
     return [[[self.fetchedResultsController sections] objectAtIndex:section] numberOfObjects]; 
    } 
} 

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

    static NSString *CellIdentifier = @"WordCell"; 
    UITableViewCell *cell = (UITableViewCell *)[self.wordTable dequeueReusableCellWithIdentifier:CellIdentifier]; 

    if (cell == nil) { 
     cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier]; 
    } 

    WordEntity *word = nil; 
    if (tableView == self.searchDisplayController.searchResultsTableView) { 
     word = [self.searchResults objectAtIndex:indexPath.row]; 
     count = self.searchResults.count; 
     self.numberWordsLabel.text = [NSString stringWithFormat:@"%lu", (unsigned long)count]; 

    } else { 

     word = [self.fetchedResultsController objectAtIndexPath:indexPath]; 
     self.numberWordsLabel.text = [NSString stringWithFormat:@"%lu", (unsigned long)fullCount]; 
    } 


    if (languageKey == 0) { 
     cell.textLabel.text = word.greekText; 
     cell.detailTextLabel.text = word.englishText; 
    } else { 
     cell.textLabel.text = word.englishText; 
     cell.detailTextLabel.text = word.greekText; 
    } 

    return cell; 
} 

/* 
Section-related methods: Retrieve the section titles and section index titles from the collation. 
*/ 


- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 
{ 
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; 
    long languageKey = [defaults integerForKey:DEFAULT_KEY_LANGUAGE_NUMBER]; 
    long count = 0; 
    if (languageKey == 0) { 
     count = 24; 
    } else { 
     count = 26; 
    } 
    return count; 
} 

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section { 
    return [sectionArray objectAtIndex:section]; 
} 
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView { 
    return sectionArray; 
} 
- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index { 
    return [collation sectionForSectionIndexTitleAtIndex:index]; 
} 

- (NSFetchedResultsController *)fetchedResultsController { 

    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] init]; 

    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; 
    long languageKey = [defaults integerForKey:DEFAULT_KEY_LANGUAGE_NUMBER ]; 
    if (languageKey == 0) { 
     sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"greekKey" ascending:YES selector:@selector(localizedCaseInsensitiveCompare:)]; 
     // sectionTitleString = @"greekKey"; 
    } else { 
     sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"englishKey" ascending:YES selector:@selector(localizedCaseInsensitiveCompare:)]; 
     // sectionTitleString = @"englishKey"; 
    } 

    NSArray *sortDescriptors = @[sortDescriptor]; 
    [fetchRequest setSortDescriptors:sortDescriptors]; 

     _fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:@"greekKey" cacheName:nil]; 
    _fetchedResultsController.delegate = self; 
    return _fetchedResultsController; 
} 

/* 
-(NSArray *)partitionObjects:(NSArray *)array collationStringSelector:(SEL)selector 

{ 
    collation = [UILocalizedIndexedCollation currentCollation]; 

    NSInteger sectionCount = [[collation sectionTitles] count]; //section count is from sectionTitles and not sectionIndexTitles 
    NSMutableArray *unsortedSections = [NSMutableArray arrayWithCapacity:sectionCount]; 

    //create an array to hold the data for each section 
    for(int i = 0; i < sectionCount; i++) 
    { 
     [unsortedSections addObject:[NSMutableArray array]]; 
    } 

    //put each object into a section 
    for (id object in array) 
    { 
     NSInteger index = [collation sectionForObject:object collationStringSelector:selector]; 
     [[unsortedSections objectAtIndex:index] addObject:object]; 
    } 

    sections = [NSMutableArray arrayWithCapacity:sectionCount]; 

    //sort each section 
    for (NSMutableArray *section in unsortedSections) 
    { 
     [sections addObject:[collation sortedArrayFromArray:section collationStringSelector:selector]]; 
    } 

    return sections; 
} 
*/ 

這是我所看到的:

enter image description here

回答

2

嘗試增加一種描述你的NSFetchRequest ...

NSSortDescriptor *sortDescriptorSecondary = [[NSSortDescriptor alloc] 
    initWithKey:@"word" ascending:YES]; 
[request setSortDescriptors:@[sectionArray, sortDescriptorSecondary]]; 

請注意,當您在表格視圖中使用部分時,必須先按部分先排序,然後再按其他條件進行排序。


UPDATE

在更詳細一點...

專用屬性包括:

@property (nonatomic, strong) NSArray *sectionArray; 

讀取請求包括:

// Declare sort descriptors 
    NSArray *requestSortDescriptors = nil; 
    NSSortDescriptor *sortDescriptorPrimary = nil; 
    NSSortDescriptor *sortDescriptorSecondary = nil; 

    // Set sort descriptors... 
    // Primary sort descriptor is your section array - sort by sections first. 
    sortDescriptorPrimary = [NSSortDescriptor sortDescriptorWithKey:self.sectionArray ascending:YES]; 
    // Secondary sort descriptor is your entity attribute `word` - sort by fetched data second. 
    sortDescriptorSecondary = [NSSortDescriptor sortDescriptorWithKey:@"word" ascending:YES]; 

    // Set sort descriptor array 
    requestSortDescriptors = @[sortDescriptorPrimary, sortDescriptorSecondary]; 

    // Apply sort descriptors to fetch request 
    [request setSortDescriptors:requestSortDescriptors]; 

希望這個助攻,讓我知道如果你需要進一步的解釋。


第二次更新

我忽略提及如何將部分數據傳播。

就個人而言,對於要在帶有節標題的TVC中顯示的數據,對於每個實體,我定義了一個實體屬性,我始終爲簡單起見請致電sectionIdentifier。然後,作爲我的數據持久化方法的一部分,我確保將「部分」數據分配給此屬性sectionIdentifier(例如在您的示例A,B,C等中)。

對於您的情況,但對於此特定示例,您已在viewDidLoad TVC生命週期方法中建立了一個名爲sectionArray的局部變量。

使用你的代碼記住,我建議以下(每個以上)...

專用屬性包括:

@property (nonatomic, strong) NSArray *sectionArray; 

而且始終將您的代碼的工作,我建議以下的(新)...

改變你的TVC的生命週期方法viewDidLoad

- (void)viewDidLoad { 
    [super viewDidLoad]; 

    self.sectionArray = nil; 
    self.collation = [UILocalizedIndexedCollation currentCollation]; 

    if (languageKey == 0) { 
     self.sectionArray = [NSArray arrayWithArray:[@"|α,ά|β|γ|δ|ε,έ|ζ|η,ή|θ|ι,ί|κ|λ|μ|ν|Ξ|ο,ό|π|ρ|σ|τ|υ,υ|φ|χ|ψ|ω,ώ|#" 
         componentsSeparatedByString:@"|"]]; 

    } else { 
     self.sectionArray = [NSArray arrayWithArray:[@"A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z|#" 
         componentsSeparatedByString:@"|"]]; 
    } 

    // I have commented out code following because I cannot see where you are using it. 
    // Does the compiler not throw up warnings for this fetch request? 
    // 
    // NSManagedObjectContext *context = [self managedObjectContext]; 
    // NSEntityDescription *entityDescription = [NSEntityDescription entityForName:@"WordEntity" inManagedObjectContext:context]; 
    // NSFetchRequest *request = [[NSFetchRequest alloc] init]; 
    // [request setEntity:entityDescription]; 
    // [request setPredicate:[self predicate]]; 
    // [request setIncludesSubentities:NO]; 

    filteredWordsArray = [[NSMutableArray alloc] init]; 
    self.searchResults = [NSMutableArray arrayWithCapacity:[[self.fetchedResultsController fetchedObjects] count]]; 

    self.searchDisplayController.searchResultsTableView.rowHeight = wordTable.rowHeight; 
} 

還在考慮您的代碼,我建議下面的(新)...

改變你NSFetchedResultsController getter方法:

- (NSFetchedResultsController *)fetchedResultsController { 
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; 
    long languageKey = [defaults integerForKey:DEFAULT_KEY_LANGUAGE_NUMBER ]; 

    // Set up fetch request 
    NSFetchRequest *fetchRequest = [[NSFetchRequest fetchRequestWithEntityName:@"WordEntity"]; 
    [fetchRequest setPredicate:[self predicate]]; 
    [fetchRequest setIncludesSubentities:NO]; 

    // Declare sort descriptor variables 
    NSArray *requestSortDescriptors = nil; 
    NSSortDescriptor *sortDescriptorPrimary = nil; 
    NSSortDescriptor *sortDescriptorSecondary = nil; 

    // Set sort descriptors... 
    // Primary sort descriptor is your section array - sort by sections first. 
    sortDescriptorPrimary = [NSSortDescriptor sortDescriptorWithKey:self.sectionArray 
                  ascending:YES]; 

    // Secondary sort descriptor is your entity attribute - sort by fetched data second. 
    if (languageKey == 0) { 
     sortDescriptorSecondary = [NSSortDescriptor sortDescriptorWithKey:@"greekKey" 
                   ascending:YES 
                   selector:@selector(localizedCaseInsensitiveCompare:)];  
     // sectionTitleString = @"greekKey"; 

    } else { 
     sortDescriptorSecondary = [NSSortDescriptor sortDescriptorWithKey:@"englishKey" 
                   ascending:YES 
                   selector:@selector(localizedCaseInsensitiveCompare:)];  
     // sectionTitleString = @"englishKey"; 

    } 

    // Set sort descriptor array - section first, then table view data 
    requestSortDescriptors = @[sortDescriptorPrimary, sortDescriptorSecondary]; 

    // Apply sort descriptors to fetch request 
    [fetchRequest setSortDescriptors:requestSortDescriptors]; 

    // Your sectionNameKeyPath in your FRC is self.sectionArray (this may be incorrect - try) 
    _fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest 
                    managedObjectContext:self.managedObjectContext 
                     sectionNameKeyPath:self.sectionArray 
                       cacheName:nil]; 

    _fetchedResultsController.delegate = self; 

    return _fetchedResultsController; 
} 
+0

感謝安德魯。我將如何搜索第一部分,以及之後的其他內容?此外,您的代碼片段將實體顯示爲關鍵字。那是故意的嗎?非常感謝您花時間回答.. +1 – 2014-09-06 16:33:49

+0

是的大衛我的錯誤實體不作爲關鍵,實體屬性作爲關鍵。 – andrewbuilder 2014-09-07 08:15:57

+0

安德魯,這真的很有幫助。謝謝!..更多缺少的一塊..如何正確填充sectionArray? – 2014-09-07 08:38:52