0

我有一個UITableView這是從核心數據由NSFetchedResultsController填充。一切都很好。但是,我剛剛在UITableView的頂部實施了UISegmentedControl,我想對結果進行排序。有三個部分:@"All", @"Boys", @"Girls"。在viewDidLoad中,我用三個NSFetchedResultsController實例化了一個NSDictionary。每個謂詞都具有完全相同的提取請求並具有不同的謂詞。UITableView UI不會刷新到新的NSFetchedResultsController的數據

 allFetchRequest.predicate = [NSPredicate predicateWithFormat:@"school.schoolID == %@", [NSNumber numberWithInt:[_schoolID intValue]]]; 
     boysFetchRequest.predicate = [NSPredicate predicateWithFormat:@"school.schoolID == %@ AND gender == %@", [NSNumber numberWithInt:[_schoolID intValue]], @"M"]; 
     girlsFetchRequest.predicate = [NSPredicate predicateWithFormat:@"school.schoolID == %@ AND gender == %@", [NSNumber numberWithInt:[_schoolID intValue]], @"F"]; 

UISegmentControl值改變時,我調用哪個視圖控制器的「currentFetchedResultsController」實例變量變爲該段的相應NSFetchedResultsController的方法,調用執行取,然後在主線程上的tableView調用reloadData

- (void)showBoys 
{ 
    self.currentFetchedResultsController = self.fetchResultsControllerDictionary[@"boys"]; 
    [self.currentFetchedResultsController performFetch:nil]; 
    [self.tableView performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:NO]; 
} 

這一切似乎工作很好,除了UITableView似乎永遠不會更新其用戶界面。它似乎顯示了所有人,男孩和女孩的正確人數,但每個指標的對象並沒有改變。例如,假設我們在覈心數據中有11個人。五個人,六個女孩。視圖加載了預先選擇的「全部」部分,所有11個人加載到UITableView中。但是,當我將段切換到「男孩」時,行數將降至五,但這些行中的對象永遠不會改變。 UITableView將繼續顯示已經在表格中的前五個對象,即使其中一些是女孩(性別==「F」的「F」)。

我知道,獲取正常工作,因爲我已經設置了一個小測試:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    User *user = [self.currentFetchedResultsController objectAtIndexPath:indexPath]; 
    NSLog(@"Username = %@ & Gender = %@", user.username, user.gender); 
} 

現在,當我選擇一排,它記錄了正確的用戶名和性別,應該是在那個indexPath。但是,登錄的用戶名與該行中的UITableView中顯示的用戶名不同。

表視圖數據源方法:

- (UserTableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    static NSString *CellIdentifier = @"Home Ranked Cell"; 

    UserTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath]; 

    User *user = [self.currentFetchedResultsController objectAtIndexPath:indexPath]; 

    NSString *name = user.name; 
    if(!name || [name isEqualToString:@""]) 
     name = user.username; 

    cell.name.text = name; 

    UserTableViewCell *previousCell = nil; 

    if(indexPath.row != 0) 
     previousCell = (UserTableViewCell *)[self tableView:tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:indexPath.row - 1 inSection:indexPath.section]]; 

    NSInteger previousVotes = 0; 

    if(previousCell) 
     previousVotes = [previousCell.votes.text integerValue]; 

    if(!previousCell) { 
     cell.rank.text = [NSString stringWithFormat:@"%i", 1]; 
    } else if(previousVotes == [user.votes integerValue]) { 
     cell.rank.text = previousCell.rank.text; 
    } else { 
     cell.rank.text = [NSString stringWithFormat:@"%i", [previousCell.rank.text integerValue] + 1]; 
    } 

    if(user.profilePicture && user.profilePicture.thumbnailData && ![user.profilePicture.thumbnailData isEqualToString:@""]) { 
     NSData *imageData = [[NSData alloc] initWithBase64EncodedString:user.profilePicture.thumbnailData options:0]; 
     cell.imageView.image = [UIImage imageWithData:imageData]; 
    } 

    if(!cell.imageView.image) 
     cell.imageView.image = [UIImage imageNamed:@"xIcon.png"]; 

    cell.votes.text = [NSString stringWithFormat:@"%i", [user.votes integerValue]]; 
    cell.upButton.tag = indexPath.row; 
    cell.downButton.tag = indexPath.row; 

    return cell; 
} 

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    User *user = [self.currentFetchedResultsController objectAtIndexPath:indexPath]; 
    NSLog(@"Username = %@ & Gender = %@", user.username, user.gender); 
} 

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

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

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section 
{ 
    return self.segmentControl; 
} 

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 
{ 
    return [[self.currentFetchedResultsController sections] count]; 
} 

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 
{ 
    id sectionInfo = [[self.currentFetchedResultsController sections] objectAtIndex:section]; 
    return [sectionInfo numberOfObjects]; 
} 

我已經試過幾乎所有。我已經經歷了每一個相關的線程,沒有任何工作。我究竟做錯了什麼?

**最新調查結果: 選中單元格後,單元格不會突出顯示(或顯示任何UI更改),除非它是該特定索引路徑的正確單元格。例如,假設所有用戶的Sally在第0行,而Tom在第1行。如果我將UISegmentedControl切換到「Male」並點擊第一個單元格(第0行,它現在顯示Sally),那麼絕對沒有UI指示單元已被點擊,儘管tableView:didSelectRowAtIndexPath仍然被調用,記錄屬於那裏的單元信息(Tom的用戶信息,因爲他屬於「Male」用戶的第0行)。

+0

你會從你的UITableViewDataSource方法發佈代碼嗎? – paulmelnikow

+0

我已經發布了他們。我意識到,我處理這種方式可能效率低下(在三個單獨的NSFetchedResultsControllers之間切換),所以我非常樂於接受其他解決方案。 –

+0

您是否爲' - [NSFetchResultsController委託]'實現了所有必要的委託方法? http://www.raywenderlich.com/999/core-data-tutorial-for-ios-how-to-use-nsfetchedresultscontroller –

回答

2

在我看來,將分段邏輯放入抓取的結果控制器方法會更容易。切換分段控制時,只需將FRC設置爲nil並在FRC創建代碼中考慮適當的過濾器。你不需要3個FRC。因此:

-(void)segmentedControlDidChange:(UISegmentedControl*)control { 
    self.fetchedResultsController = nil; 
    [self.tableView reloadData]; 
} 

和創建FRC時:

NSPredicate *basePredicate = [NSPredicate predicateWithFormat: 
     @"school.schoolID = %@", _schoolID]; 
NSPredicate *secondPredicate = [NSPredicate predicateWithValue:YES]; 
NSInteger i = self.segmentedControl.selectedSegmentIndex; 
if (i > 0) { 
    secondPredicate = [NSPredicate predicateWithFormat: 
    @"gender = %@", i == 1 ? @"M" : @"F"]; 
} 
fetchRequest.predicate = [NSCompoundPredicate 
    andPredicateWithSubPredicates:@[basePredicate, secondPredicate]]; 
+0

雖然這確實有助於清理一些事情,但它並沒有解決我的問題。**進一步的測試使我能夠找到問題的一個新的有趣方面,我將添加到原始文章中。 –

+0

雖然這並沒有解決您的問題,但它仍然值得加票;-)。 – Mundi

0

原來初始化我的UITableViewCell時,我犯了一個愚蠢的錯誤。與其說

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 

的我打電話

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier **forIndexPath:indexPath**]; 

後者返回當前的UITableViewCell從提到的indexPath出隊。出於某種原因,如果單元格從現有單元出列,單元格上的屬性是隻讀的,導致我的所有更改都被忽略。我希望這可以幫助未來的人,因爲我沒有在堆棧溢出中看到任何有關此問題的信息,在分析每行代碼幾小時後,我偶然偶然發現了我的錯誤。

相關問題