UITableView UI不会刷新到新NSFetchedResultsController的数据

时间:2014-04-26 03:13:58

标签: ios iphone uitableview core-data nsfetchedresultscontroller

我有一个UITableViewNSFetchedResultsController从核心数据中填充。一切都很好。但是,我刚刚在UISegmentedControl的顶部实施了UITableView,我想对结果进行排序。有三个部分:@"All", @"Boys", @"Girls"。在viewDidLoad中,我实例化了一个NSDictionary,其中包含三个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,调用执行fetch,然后在主线程中的tableView上调用reloadData

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

除了UITableView似乎永远不会更新其UI之外,这一切似乎都很有效。它似乎显示了所有人,男孩和女孩的正确部分数量,但每个指数的对象都没有变化。例如,假设我们在核心数据中有11个人。五个家伙,六个女孩。视图加载了" All"段预选,所以所有11人加载到UITableView。但是,当我将段切换到" Boys"时,行数将减少到5,但这些行中的对象永远不会改变。 UITableView将继续显示表格中已有的前五个对象,即使有些女孩(性别==" F" {{1} })。

我知道fetch工作正常,因为我已经设置了一个小测试:

Core Data

现在,当我选择一行时,它会记录应该位于该- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { User *user = [self.currentFetchedResultsController objectAtIndexPath:indexPath]; NSLog(@"Username = %@ & Gender = %@", user.username, user.gender); } 的正确用户名和性别。但是,记录的用户名与该行indexPath中显示的用户名不同。

表视图数据源方法:

UITableView

我几乎尝试了一切。我已经完成了所有相关的线程,没有任何工作。我做错了什么?

**最新发现: 选择单元格后,单元格不会突出显示(或显示任何UI更改),除非它是该特定索引路径的正确单元格。例如,让我们说Sally在所有用户的第0行,而Tom在第1行。如果我将UISegmentedControl切换到" Male"然后点击第一个单元格(第0行,当前显示Sally),尽管仍然会调用tableView:didSelectRowAtIndexPath,但仍然没有用于指示单元格被点击的UI指示,记录了属于那里的单元格信息(Tom&#39用户) info,因为他属于"男性"用户)的第0行。

2 个答案:

答案 0 :(得分: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]];

答案 1 :(得分:0)

事实证明,在初始化我的UITableViewCell时,我犯了一个愚蠢的错误。而不是打电话

 UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

我正在打电话

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

后者返回从提到的indexPath中出列的当前UITableViewCell。由于某种原因,如果单元格从现有单元格中出列,则单元格上的属性是只读的,导致我的所有更改都被忽略。我希望这对未来的某些人有所帮助,因为我在Stack Overflow上没有看到任何关于这一点的事情,我偶然发现在经过数小时的每行代码分析之后偶然发现了我的错误。