由于我无法真正描述此错误,因此我在屏幕上显示错误。 http://www.youtube.com/watch?v=w2FqKKcL2Ck&feature=youtu.be 基本上我不知道该怎么做。当用户完成“要完成的任务”部分中的所有任务时,我希望部分标题保留在那里......只是没有任何对象(仅仅因为它需要添加更多任务)。
幸运的是,当用户没有任何已完成的任务时,那里的标题会消失,这应该是什么。我希望顶部标题不会消失......
此外,与删除相同。当删除最后一个对象时,我真的不希望完成任务部分完全消失。
我听说除非你使用像TAFetchResultsController这样的自定义子类,否则这是不可能的,但是我尝试使用它,这对我来说实现起来太复杂了(并且破坏了我的应用程序而不是修复它)。也许你们有一些建议吗?
以下是一些相关代码:
任务核心数据属性
@interface Tasks : NSManagedObject
@property (nonatomic, retain) NSString *sectionString;
@end
@implementation Tasks
@dynamic sectionString;
@end
将任务添加到不同的部分
NSManagedObjectContext *context = self.managedObjectContext;
NSManagedObject *startingTask = [NSEntityDescription insertNewObjectForEntityForName:@"Tasks" inManagedObjectContext:context];
[startingTask setValue:@"Eat Dinner" forKey:@"taskName"];
[startingTask setValue:[NSNumber numberWithDouble:400] forKey:@"timeInterval"];
[startingTask setValue:@"Tasks To Complete" forKey:@"sectionString"];
NSManagedObject *finishedTask = [NSEntityDescription insertNewObjectForEntityForName:@"Tasks" inManagedObjectContext:context];
[finishedTask setValue:@"Do Laundry" forKey:@"taskName"];
[finishedTask setValue:[NSNumber numberWithDouble:400] forKey:@"timeInterval"];
[finishedTask setValue:@"Completed Tasks" forKey:@"sectionString"];
NSError *error;
if (![context save:&error]) {
NSLog(@"couldn't save: %@", [error localizedDescription]);
}
TableViewController.m:
-(void) viewDidLoad{
// ---Start Core Data With NSFetchedResultsController---
[super viewDidLoad];
NSError *error;
if (![[self fetchedResultsController] performFetch:&error]){
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
exit(-1);
}
// ---End Core Data w/ NSFetchedResultsController---
[self.tableView setDelegate:self];
[self setModalTransitionStyle:UIModalTransitionStyleCrossDissolve];
holdViewsArray = [[NSMutableArray alloc]init];
UIView *seperatorView;
UIView *seperatorView2;
NSString *sectionTitle = @"Tasks To Complete";
NSString *section2Title = @"Completed Tasks";
UILabel *label = [[UILabel alloc]init];
UILabel *label2 = [[UILabel alloc]init];
label.frame = CGRectMake(10.0, 5.0, 320.0, 50.0);
label.text = sectionTitle;
label2.frame = CGRectMake(10.0, 0.0, 320.0, 40.0);
label2.text = section2Title;
headerView = [[UIView alloc]initWithFrame:label.frame];
headerView2 = [[UIView alloc]initWithFrame:label2.frame];
CGRect sepFrame = CGRectMake(0, headerView.frame.size.height-2, 320, 1);
CGRect sep2Frame =CGRectMake(0, headerView2.frame.size.height-2, 320, 1);
seperatorView = [[UIView alloc] initWithFrame:sepFrame];
seperatorView2 = [[UIView alloc]initWithFrame:sep2Frame];
[headerView addSubview:seperatorView];
[headerView2 addSubview:seperatorView2];
[headerView addSubview:label];
[headerView addSubview:button];
[headerView2 addSubview:label2];
[holdViewsArray addObject:headerView];
[holdViewsArray addObject:headerView2];
- (NSFetchedResultsController *)fetchedResultsController {
if (_fetchedResultsController != nil) {
return _fetchedResultsController;
}
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription
entityForName:@"Tasks" inManagedObjectContext:managedObjectContext];
[fetchRequest setEntity:entity];
NSSortDescriptor *isCompleted = [[NSSortDescriptor alloc]initWithKey:@"sectionString" ascending:NO];
NSSortDescriptor *sort = [[NSSortDescriptor alloc]
initWithKey:@"dateCreated" ascending:YES];
[fetchRequest setSortDescriptors:@[isCompleted, sort]];
[fetchRequest setFetchBatchSize:20];
NSFetchedResultsController *theFetchedResultsController =
[[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
managedObjectContext:managedObjectContext sectionNameKeyPath:@"sectionString"
cacheName:nil];
self.fetchedResultsController = theFetchedResultsController;
_fetchedResultsController.delegate = self;
return _fetchedResultsController;
}-(void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath {
Tasks *task = [_fetchedResultsController objectAtIndexPath:indexPath];
cell.textLabel.text = task.taskName.uppercaseString;
cell.detailTextLabel.text = [NSString stringWithFormat:@"%.0f", task.timeInterval];
cell.imageView.image = [UIImage imageNamed:@"unchecked.png"];
cell.imageView.highlightedImage = [UIImage imageNamed:@"uncheckedhighlighted.png"];
[cell setAccessoryType:UITableViewCellAccessoryDisclosureIndicator];
if (indexPath.section == 1)
[cell.contentView setAlpha:0.5];
else {
[cell.contentView setAlpha:1];
}
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(handlechecking:)];
[cell.imageView addGestureRecognizer:tap];
cell.imageView.userInteractionEnabled = YES;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
cellSubclassCell *cell = [tableView dequeueReusableCellWithIdentifier:@"UITableViewCell"];
if (!cell)
cell = [[cellSubclassCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"UITableViewCell"];
[self configureCell:cell atIndexPath:indexPath];
return cell;
}
-(void)handlechecking:(UITapGestureRecognizer *)t{
CGPoint tapLocation = [t locationInView:self.tableView];
NSIndexPath *tappedIndexPath = [self.tableView indexPathForRowAtPoint:tapLocation];
Tasks *task = [_fetchedResultsController objectAtIndexPath:tappedIndexPath];
if ([task.sectionString isEqual: @"Tasks To Complete"]){
task.sectionString = @"Completed Tasks";
} else if ([task.sectionString isEqualToString:@"Completed Tasks"]){
task.sectionString = @"Tasks To Complete";
}
[self.tableView reloadData];
NSTimeInterval time = [[NSDate date] timeIntervalSinceReferenceDate];
[task setDateCreated:time];
}
-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{
switch (section) {
case 0:
return [holdViewsArray objectAtIndex:0];
break;
case 1:
return [holdViewsArray objectAtIndex:1];
break;
}
return 0;
}
答案 0 :(得分:0)
NSFetchedResultsController
推断fetch返回的对象中的部分。因此,如果一个部分的项目数量为零,该部分就会消失。这就是NSFetchedResultsController
的工作方式。
您最简单的选择可能是第三方框架。看看TLIndexPathTools。它提供了NSFetchedResultsController
的替代方案,它不需要核心数据或NSFetchRequest
,这意味着您可以在更多场景中使用它。看看一些示例项目(Core Data one称为"Core Data") - 一些很酷的事情只需几行代码即可完成。
TLIndexPathTools支持空部分,但不是以您需要的方式显式支持。但是,您可以通过覆盖TLIndexPathController
来完成几行代码。代码看起来像这样:
@interface MyIndexPathController : TLIndexPathController
@end
#import "MyIndexPathController.h"
@implementation MyIndexPathController
- (void)setDataModel:(TLIndexPathDataModel *)dataModel
{
if ([dataModel sectionForSectionName:@"MyFirstSectionName"] == NSNotFound) {
TLIndexPathSectionInfo *firstSection = [[TLIndexPathSectionInfo alloc] initWithItems:nil andName:@"MyFirstSectionName"];
NSMutableArray *sectionInfos = [NSMutableArray arrayWithArray:dataModel.sections];
[sectionInfos insertObject:firstSection atIndex:0];
dataModel = [[TLIndexPathDataModel alloc] initWithSectionInfos:sectionInfos andIdentifierKeyPath:dataModel.identifierKeyPath andCellIdentifierKeyPath:dataModel.cellIdentifierKeyPath];
}
super.dataModel = dataModel;
}
@end
这里发生的是我们拦截控制器生成的数据模型(基于我们的获取请求的结果)并检查感兴趣的部分是否存在。如果没有,我们创建一个空的section info对象,并将它与其他section infos组合成一个新的数据模型,并将它传递给超类。
如果需要,一般扩展到使用任何必需部分集合应该不会太困难。