UITableView核心数据重新排序

时间:2010-03-02 04:38:37

标签: iphone objective-c cocoa-touch uitableview core-data

我之前已经问过这个问题了,我看了this question的答案。但是,我仍然对如何在Core Data项目中使用UITableView实现重新排序感到困惑。我所知道的是我需要在我的实体中有一个“displayOrder”属性来跟踪项目的顺序,我需要枚举获取结果中的所有对象并设置它们的displayOrder属性。

在我链接的问题中的给定代码中,表视图委托方法调用类似于此[self FF_fetchResults];的方法,并且没有给出该方法的代码,因此很难确定它究竟是什么。< / p>

是否有任何示例代码可以证明这一点?这比分享大块代码更简单。

由于

1 个答案:

答案 0 :(得分:57)

我不确定你遇到麻烦的部分(基于评论)......但这是我的建议。 displayOrder只是NSManagedObject类的一个简单属性。如果可以保存托管对象,则可以完成此功能。让我们先来看一个简单的NSManagedObject:

@interface RowObj :  NSManagedObject  
{
}

@property (nonatomic, retain) NSString *rowDescription;
@property (nonatomic, retain) NSNumber *displayOrder;

接下来,我们需要在tableview中显示数据的本地副本。我已经阅读了您所做的评论,但我不确定您是否使用了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获取数据。当我必须这样做时,我有一些帮助(称之为你想要的)对象做的工作。典型的查找方法如下所示:

- (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:method:

要更新显示顺序,您需要覆盖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];
    }   
}