use*_*007 1 core-data uitableview nsfetchedresultscontroller ios
我在这里有一个错误,我找不到它所以我希望你敏锐的眼睛会!
我正在使用带有tableView的FRC.FRC是按keyPath排序的部分,然后按"displayOrder"排序 - 通常.
每个部分中的详细信息"displayOrder"从1开始,因此当我插入项目时,在另一个方法中,它将转到该部分的索引0.
我想循环遍历受影响的部分,并从1开始重新分配"displayOrder".
在重新订购期间,代码适用于:在任何部分内重新排序,因为重新排序的单元格向上移动而不是向下移动.
代码不适用于...单击单元格但不移动它.代码因某种原因改变了顺序,从而改变了单元格的顺序. - 当我单击一个单元格时,它与其上方的其他单元格在同一部分重新排序.
我以前有这个工作,我不知道发生了什么.
谢谢你的帮助.
-Edited-
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath
NSError *error = nil;
NSManagedObjectContext *context = [self.fetchedResultsController managedObjectContext];
TheDetail *fromThing = [self.fetchedResultsController objectAtIndexPath:fromIndexPath];
TheDetail *toThing = [self.fetchedResultsController objectAtIndexPath:toIndexPath];
NSPredicate *catetgoryPredicate = [NSPredicate predicateWithFormat:@"relationshipToTheCategory.name == %@", fromThing.relationshipToTheCategory.name];
NSMutableArray *allThings = [[[self.fetchedResultsController fetchedObjects] filteredArrayUsingPredicate:catetgoryPredicate] mutableCopy];
NSPredicate *fromPredicate = [NSPredicate predicateWithFormat:@"relationshipToTheSection.name == %@", fromThing.relationshipToTheSection.name];
NSPredicate *toPredicate = [NSPredicate predicateWithFormat:@"relationshipToTheSection.name == %@", toThing.relationshipToTheSection.name];
[allThings removeObject:fromThing];
[allThings insertObject:fromThing atIndex:toIndexPath.row];
//if the sections are NOT the same, reorder by section otherwise reorder the one section
if (![fromThing.relationshipToTheSection.name isEqual:toThing.relationshipToTheSection.name]) {
//Change the from index section's relationship and save, then grab all objects in sections and re-order
[fromThing setRelationshipToTheSection:toThing.relationshipToTheSection];
if ([context save:&error]) {
NSLog(@"The setting section save was successful!");
} else {
NSLog(@"The setting section save was not successful: %@", [error localizedDescription]);
}
NSMutableArray *fromThings = [[allThings filteredArrayUsingPredicate:fromPredicate]mutableCopy];
NSInteger i = 1;
for (TheDetail *fromD in fromThings) {
[fromD setValue:[NSNumber numberWithInteger:i] forKey:@"displayOrder"];
i++;
}
//reset displayOrder Count, the re-order the other section
i = 1;
NSMutableArray *toThings = [[allThings filteredArrayUsingPredicate:toPredicate]mutableCopy];
for (TheDetail *toD in toThings) {
[toD setValue:[NSNumber numberWithInteger:i] forKey:@"displayOrder"];
i++;
}
} else {
NSMutableArray *fromThings = [[allThings filteredArrayUsingPredicate:fromPredicate]mutableCopy];
NSInteger i = 1;
for (TheDetail *fromD in fromThings) {
[fromD setValue:[NSNumber numberWithInteger:i] forKey:@"displayOrder"];
i++;
}
}
if ([context save:&error]) {
NSLog(@"The save was successful!");
} else {
NSLog(@"The save was not successful: %@", [error localizedDescription]);
}
Run Code Online (Sandbox Code Playgroud)
FRC
if (_fetchedResultsController != nil)
{
return _fetchedResultsController;
}
NSManagedObjectContext *context = [[self appDelegate]managedObjectContext];
//Construct the fetchResquest
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc]init];
NSEntityDescription *detail = [NSEntityDescription entityForName:@"TheDetail" inManagedObjectContext:context];
[fetchRequest setEntity:detail];
//Add predicate
NSString *category = @"1";
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"relationshipToTheCategory == %@", category];
[fetchRequest setPredicate:predicate];
//Add sort descriptor
NSSortDescriptor *sortDescriptor2 = [NSSortDescriptor sortDescriptorWithKey:@"relationshipToTheSection.displayOrder" ascending:YES];
NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"displayOrder" ascending:YES];
NSArray *sortDescriptors = [[NSArray alloc]initWithObjects:sortDescriptor2, sortDescriptor, nil];
[fetchRequest setSortDescriptors:sortDescriptors];
//Set fetchedResultsController
NSFetchedResultsController *theFetchedResultsController = [[NSFetchedResultsController alloc]initWithFetchRequest:fetchRequest managedObjectContext:context sectionNameKeyPath:@"relationshipToTheSection.name" cacheName:@"Root"];
NSError *error = nil;
self.fetchedResultsController = theFetchedResultsController;
self.fetchedResultsController.delegate = self;
[self.fetchedResultsController performFetch:&error];
return _fetchedResultsController;
Run Code Online (Sandbox Code Playgroud)
新错误
Section *toSection = [[self fetchedResultsController] sections][[toIndexPath section]];
NSString *toSectionName = [[[toSection objects] lastObject] name];
Run Code Online (Sandbox Code Playgroud)
在这里我得到IB中的错误"没有可见的@interface for"DSection"声明选择器'对象'.
Mar*_*rra 12
不要删除自己作为代表NSFetchedResultsController.这违背了该类的预期设计.如果那是"帮助"那么它掩盖了一个真正的问题.
不要用-performFetch;这种方法打电话.在NSFetchedResultsController将检测到的变化,并告诉你委托他们.
不要用-reloadData这种方法打电话.让委托方法进行NSFetchedResultsController重新排序.
总是,始终始终捕获核心数据保存上的错误.即使你真的不需要在这里保存(这是用保存阻止UI的不好的时候),你应该总是捕获错误,然后观察结果,否则隐藏错误.
目前尚不清楚它在-save:做什么.你没有改变任何东西.
所以这是你正在做的很多工作,你不需要这样做.你正在与框架作斗争并使事情变得更难.
我认为你的重新排序逻辑比它需要的更复杂.它也有助于查看NSFetchedResultsController初始化.但我猜你有基于的部分name,然后按顺序排序displayOrder.如果是这种情况,这个代码可以更清洁,这将使问题更加明显.
我的问题是,你是否用断点检查?当一行未实际移动时,此代码是否会触发?如果你检查,看看是否您toIndexPath和fromIndexPath是平等的吗?
您无需在此处保存上下文.这是一种UI方法,保存会导致延迟,这会使UI响应缓慢. 稍后再保存.
您不需要在此处运行NSFetchRequest.这也会击中磁盘并导致UI延迟.您需要的每一条信息都已经存在于您的内存中NSFetchedResultsController.使用现有对象关系来检索您做出决策所需的数据.
调用实体The*违反了Objective-C命名约定.像"the","is","are"这样的词不属于实体或类名.
考虑这个版本的代码:
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath
{
NSManagedObjectContext *context = [[self fetchedResultsController] managedObjectContext];
TheDetail *fromThing = [[self fetchedResultsController] objectAtIndexPath:fromIndexPath];
Section *toSection = [[self fetchedResultsController] sections][[toIndexPath section]];
NSString *toSectionName = [[[toSection objects] lastObject] name];
NSString *fromSectionName = [[fromThing relationshipToTheSection] name];
if ([toSectionName isEqualToString:fromSectionName]) {
//Same section, easy reorder
//Move the object
NSMutableArray *sectionObjects = [[[[self fetchedResultsController] sections][[fromIndexPath section]] objects] mutableCopy];
[sectionObjects removeObject:fromThing];
[sectionObjects insertObject:fromThing atIndex:[toIndexPath row]];
//Reorder
NSInteger index = 1;
for (TheDetail *thing in sectionObjects) {
[thing setValue:@(index) forKey:@"displayOrder"];
}
return; //Early return to keep code on the left margin
}
NSMutableArray *sectionObjects = [[[[self fetchedResultsController] sections][[fromIndexPath section]] objects] mutableCopy];
[sectionObjects removeObject:fromThing];
//Reorder
NSInteger index = 1;
for (TheDetail *thing in sectionObjects) {
[thing setValue:@(index) forKey:@"displayOrder"];
}
if ([[toSection numberOfObjects] count] == 0) {
[fromThing setValue:@(0) forKey:@"displayOrder"];
//How do you determine the name?
return;
}
sectionObjects = [[toSection objects] mutableCopy];
[sectionObjects insertObject:fromThing atIndex:[toIndexPath row]];
//Reorder
NSInteger index = 1;
for (TheDetail *thing in sectionObjects) {
[thing setValue:@(index) forKey:@"displayOrder"];
}
}
Run Code Online (Sandbox Code Playgroud)
没有抓取也没有保存.我们只使用内存中的内容,因此它非常快.这应该是C&P-able,除了我留下的评论之一.
| 归档时间: |
|
| 查看次数: |
1256 次 |
| 最近记录: |