我有一个UITableView
由NSFetchedResultsController
从核心数据中填充。一切都很好。但是,我刚刚在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行。
答案 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上没有看到任何关于这一点的事情,我偶然发现在经过数小时的每行代码分析之后偶然发现了我的错误。