Переупорядочение Данных Ядра UITableView

Я знаю, что этот вопрос задали прежде, и я смотрел на ответ на этот вопрос. Однако я все еще смущен относительно того, как реализовать переупорядочение с UITableView в Базовом проекте Данных. То, что я знаю, - то, что у меня должен быть атрибут "displayOrder" в моем Объекте для отслеживания порядка пунктов, и я должен перечислить через все объекты в выбранных результатах и установить их атрибут displayOrder.

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

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

Спасибо

26
задан Community 23 May 2017 в 12:08
поделиться

1 ответ

Я не уверен, с какой частью у вас проблемы (судя по комментариям)... но вот мое предложение. DisplayOrder - это простой атрибут класса NSManagedObject. Если вы можете сохранить управляемый объект, то вы сможете доработать эту функцию. Сначала возьмем простой NSManagedObject:

@interface RowObj :  NSManagedObject  
{
}

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

Далее, нам нужно иметь локальную копию данных, отображаемых в табличном представлении. Я прочитал ваши комментарии и не совсем понимаю, используете ли вы 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];
}

Здесь происходит две вещи... (я объясню 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]. Это встроенная функция, которая возвращает элемент кнопки на панели, название и связанное с ним состояние которой переключается между 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];
    }   
}
57
ответ дан 28 November 2019 в 06:50
поделиться
Другие вопросы по тегам:

Похожие вопросы: