UITableView 核心数据重新排序 [英] UITableView Core Data reordering

查看:27
本文介绍了UITableView 核心数据重新排序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I know this question has been asked before, and I took a look at the answer to this question. However, I'm still confused as to how to implement reordering with a UITableView in a Core Data project. What I know is that I need to have a "displayOrder" attribute in my Entity to track the order of items, and I need to enumerate through all the objects in the fetched results and set their displayOrder attribute.

在我链接的问题中的给定代码中,表视图委托方法调用了这样的方法[self FF_fetchResults];,并且没有给出该方法的代码,因此很难告诉它到底是什么.

In the given code in the question I linked to, the table view delegate method calls a method like this [self FF_fetchResults];, and the code for that method is not given so its hard to tell what exactly it is.

是否有任何示例代码可以证明这一点?与共享大量代码相比,这看起来更简单.

Is there any sample code that demonstrates this? That would be simpler to look at than sharing large chunks of code.

谢谢

推荐答案

我不确定您在哪个部分遇到了问题(根据评论)...但这是我的建议.displayOrder 只是 NSManagedObject 类上的一个简单属性.如果您可以保存管理对象,那么您将能够完成此功能.让我们先来看一个简单的 NSManagedObject:

I'm not sure which part you are having trouble with (based on the comments)... but here is my suggestion. The displayOrder is just a simple attribute on a NSManagedObject class. If you can save a managed object, then you will be able finish this feature. Lets first take a simple NSManagedObject:

@interface RowObj :  NSManagedObject  
{
}

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

接下来,我们需要在 tableview 中显示数据的本地副本.我已经阅读了您所做的评论,但我不确定您是否在使用 FetchedResultsController.我的建议是从简单开始,只使用一个普通的 tableviewcontroller,在用户更改显示顺序时更新行数据......然后在用户完成编辑后保存订单.

Next, we need to have local copy of the data being displayed in the tableview. I have read through the comments you have made and I'm not really sure if you are using the FetchedResultsController or not. My suggestion would be to start simple and just use a normal tableviewcontroller where you update the row data whenever a user changes the display order... then save the order when the user is done editing.

这个 tableviewcontoller 的界面看起来像这样:

The interface for this tableviewcontoller would look like this:

@interface MyTableViewController : UITableViewController {
    NSMutableArray *myTableViewData;
}

@property(nonatomic,retain) NSMutableArray *myTableViewData;

@end 

接下来,我们需要在viewWillAppear方法中加载表格视图数据:

Next, we need to load the the table view data in the viewWillAppear method:

- (void)viewWillAppear:(BOOL)animated {
    myTableViewData = [helper getRowObjects]; // insert method call here to get the data
    self.navigationItem.leftBarButtonItem = [self editButtonItem];
}

这里有两件事……(稍后我将解释editButtonItem)第一件事是我们需要从CoreData 获取我们的数据.当我必须这样做时,我有某种助手(称之为你想要的)对象来完成这项工作.典型的查找方法如下所示:

There are 2 things going on here... (I'll explain the editButtonItem later) the first is that we need to get our data from CoreData. When I have to do this I have some sort of helper(call it what you want) object do the work. A typical find method would look like this:

- (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: 方法:

Now that you have your data, you can now wait for the user to edit the table. That is where the [self editButtonItem] comes into play. This is a built in feature that returns a bar button item that toggles its title and associated state between Edit and Done. When the user hits that button, it will invoke the setEditing:animated: method:

要更新显示顺序,您需要覆盖 UITableViewController 类上的 setEditing 方法.它应该看起来像这样:

To update the display order you need to override the setEditing method on the UITableViewController class. It should look something like this:

- (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 方法来更新显示顺序:

We don't have to do anything when the user is in edit mode... we only want to save once they have pressed the "Done" button. When a user drags a row in your table you can update your display order by overriding the canMoveRowAtIndexPath and moveRowAtIndexPath methods:

- (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 值的原因是因为用户仍处于编辑模式......我们不知道用户是否完成了编辑,他们甚至可以取消他们所做的没有点击完成"按钮.

Again, the reason I don't update the displayOrder value here is because the user is still in edit mode... we don't know if the user is done editing AND they could even cancel what they've done by not hitting the "Done" button.

编辑

如果您想删除一行,您需要覆盖 tableView:commitEditingStyle:forRowAtIndexPath 并执行如下操作:

If you want to delete a row you need to override tableView:commitEditingStyle:forRowAtIndexPath and do something like this:

- (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];
    }   
}

这篇关于UITableView 核心数据重新排序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆