Я не уверен, какая часть у вас возникли проблемы с (на основе комментариев) ... но вот мое предложение. DisplayOrder - просто простой атрибут класса NSManagedObject. Если вы можете сохранить управляемый объект, вы сможете завершить эту функцию. Давайте сначала взять простой NSManagedObject:
@interface RowObj : NSManagedObject
{
}
@property (nonatomic, retain) NSString *rowDescription;
@property (nonatomic, retain) NSNumber *displayOrder;
Далее, мы должны иметь локальную копию данных, которые отображаются в Tableview. Я прочитал комментарии, которые вы сделали, и я не уверен, что вы используете FetchedResultsController или нет. Мое предложение состояло бы в том, чтобы начать простой и просто использовать обычный диспетчер tableview, где вы обновляете данные о строках всякий раз, когда пользователь меняет порядок отображения ... а затем сохраняет заказ, когда пользователь закончил редактирование.
Интерфейс для этого 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];
}
Есть 2 вещи, происходящие здесь ... (я объясню позже элемент 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]. Это встроенная функция, которая возвращает элемент кнопки панели, который переключает заголовок и связанное состояние между Edit и Done. Когда пользователь нажимает на эту кнопку, он будет вызывать метод setEditing: animated::
Чтобы обновить порядок отображения, вам необходимо переопределить метод setEditing в классе UITableViewController. Это должно выглядеть примерно так:
- (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 здесь потому, что пользователь все еще режим редактирования...мы не знаем, выполняется ли редактирование пользователя, и они могут даже отменить то, что они сделали, не нажав кнопку «Готово».
EDIT
Если вы хотите удалить строку, которую нужно переопределить 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];
}
}
вы пробовали связанный код? Если вы используете выбранный контроллер результатов, вам, возможно, не нужно ничего делать. Этот метод просто извлекает объекты снова (теперь, когда сортировка изменилась). – gerry3
Спасибо, я попробую. Нужно ли снова извлекать объекты после изменения заказа? – indragie
Вам не нужно, если вы используете выбранный контроллер результатов (и имеете код плиты котла, чтобы обновить представление таблицы, когда измененный контроллер результатов изменен). – gerry3