2010-03-02 2 views
25

Я знаю, что этот вопрос задан раньше, и я взглянул на ответ this question. Тем не менее, я все еще запутался относительно того, как реализовать переупорядочение с помощью UITableView в проекте Core Data. Я знаю, что мне нужно иметь атрибут displayOrder в моем Entity, чтобы отслеживать порядок элементов, и мне нужно перечислить все объекты в полученных результатах и ​​установить их атрибут displayOrder.UITableView Core Data reordering

В данном коде в вопросе, с которым я связан, метод делегирования представления таблиц вызывает метод, подобный этому [self FF_fetchResults];, и код для этого метода не указан, поэтому трудно сказать, что это такое.

Есть ли образец кода, который демонстрирует это? Это было бы проще рассмотреть, чем обмен большими кусками кода.

Благодаря

+0

вы пробовали связанный код? Если вы используете выбранный контроллер результатов, вам, возможно, не нужно ничего делать. Этот метод просто извлекает объекты снова (теперь, когда сортировка изменилась). – gerry3

+0

Спасибо, я попробую. Нужно ли снова извлекать объекты после изменения заказа? – indragie

+0

Вам не нужно, если вы используете выбранный контроллер результатов (и имеете код плиты котла, чтобы обновить представление таблицы, когда измененный контроллер результатов изменен). – gerry3

ответ

56

Я не уверен, какая часть у вас возникли проблемы с (на основе комментариев) ... но вот мое предложение. 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]; 
    } 
} 
+0

Спасибо за подробный ответ, я попробую это. – indragie

+0

Уверен, дайте мне знать, если у вас есть какие-либо проблемы ... это в основном слово-4-слово из рабочей реализации из одного из моих приложений, поэтому оно должно помочь вам в этом. –

+0

Как насчет удаления строк? Есть ли что-то особенное, что нужно сделать там, чтобы работать с этим? – indragie

Смежные вопросы