我不确定您在哪个部分遇到了问题(基于 cmets)...但这是我的建议。 displayOrder 只是 NSManagedObject 类的一个简单属性。如果您可以保存托管对象,那么您将能够完成此功能。让我们先来看一个简单的 NSManagedObject:
@interface RowObj : NSManagedObject
{
}
@property (nonatomic, retain) NSString *rowDescription;
@property (nonatomic, retain) NSNumber *displayOrder;
接下来,我们需要在 tableview 中显示数据的本地副本。我已经阅读了您制作的 cmets,但我不确定您是否正在使用 FetchedResultsController。我的建议是从简单的开始,只需使用普通的 tableviewcontroller 来更新行数据,只要用户更改显示顺序......然后在用户完成编辑时保存顺序。
tableviewcontoller 的界面如下所示:
@interface MyTableViewController : UITableViewController {
NSMutableArray *myTableViewData;
}
@property(nonatomic,retain) NSMutableArray *myTableViewData;
@end
接下来,我们需要在 viewWillAppear 方法中加载表格视图数据:
- (void)viewWillAppear:(BOOL)animated {
myTableViewData = [helper getRowObjects]; // insert method call here to get the data
self.navigationItem.leftBarButtonItem = [self editButtonItem];
}
这里发生了两件事……(稍后我会解释editButtonItem)第一件事是我们需要从CoreData 中获取我们的数据。当我必须这样做时,我有某种帮手(称它为你想要的)对象来完成这项工作。典型的 find 方法如下所示:
- (NSMutableArray*) getRowObjects{
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"RowObj" inManagedObjectContext:[self managedObjectContext]];
[request setEntity:entity];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"displayOrder" ascending:YES];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[request setSortDescriptors:sortDescriptors];
[sortDescriptors release];
[sortDescriptor release];
NSError *error;
NSMutableArray *mutableFetchResults = [[managedObjectContext executeFetchRequest:request error:&error] mutableCopy];
if (mutableFetchResults == nil) {
// Handle the error.
}
[request release];
return mutableFetchResults;
}
现在您有了数据,现在可以等待用户编辑表格。这就是 [self editButtonItem] 发挥作用的地方。这是一个内置功能,它返回一个栏按钮项目,该项目在编辑和完成之间切换其标题和关联状态。当用户点击该按钮时,它将调用 setEditing:animated: 方法:
要更新显示顺序,您需要覆盖 UITableViewController 类的 setEditing 方法。它应该看起来像这样:
- (void)setEditing:(BOOL)editing animated:(BOOL)animated {
[super setEditing:editing animated:animated];
[myTableView setEditing:editing animated:animated];
if(!editing) {
int i = 0;
for(RowObj *row in myTableViewData) {
row.displayOrder = [NSNumber numberWithInt:i++];
}
[helper saveManagedObjectContext]; // basically calls [managedObjectContext save:&error];
}
}
当用户处于编辑模式时,我们不需要做任何事情......我们只想在他们按下“完成”按钮后保存。当用户在表格中拖动一行时,您可以通过覆盖 canMoveRowAtIndexPath 和 moveRowAtIndexPath 方法来更新显示顺序:
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath {
return true;
}
(void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath {
RowObj *row = [myTableViewData objectAtIndex:sourceIndexPath.row];
[myTableViewData removeObjectAtIndex:sourceIndexPath.row];
[myTableViewData insertObject:row atIndex:destinationIndexPath.row];
}
再一次,我不在这里更新 displayOrder 值的原因是因为用户仍处于编辑模式...我们不知道用户是否已完成编辑,他们甚至可以取消他们所做的没有点击“完成”按钮。
编辑
如果您想删除一行,您需要覆盖 tableView:commitEditingStyle:forRowAtIndexPath 并执行以下操作:
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
// Delete the managed object at the given index path.
RowObj *row = [myTableViewData objectAtIndex:indexPath.row];
[helper deleteRow:row];
// Update the array and table view.
[myTableViewData removeObjectAtIndex:indexPath.row];
[myTableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:YES];
}
}