3

Я пытаюсь изменить порядок ячеек в виде таблицы с использованием данных ядра и nsfetchresultscontroller. Я нашел несколько способов сделать это, используя Objective C (из которых я ничего не знаю) и попытался их реализации в стрижа, вот что я придумал:Как изменить порядок строк таблицы с помощью fetchedresultscontroller в swift?

var books: Array<AnyObject> = [] 

// Override to support rearranging the table view. 
override func tableView(tableView: UITableView, moveRowAtIndexPath fromIndexPath: NSIndexPath, toIndexPath: NSIndexPath) { 

    books = fetchedResultsController.fetchedObjects! 

    let book = fetchedResultsController.objectAtIndexPath(fromIndexPath) 

    self.fetchedResultsController.delegate = nil 

    books.removeAtIndex(fromIndexPath.row) 
    books.insert(book, atIndex: toIndexPath.row) 

    var i = 0 
    for book in books { 
     book.setValue(i++, forKey: "position") 
    } 

    try! context.save() 

    self.fetchedResultsController.delegate = self 

} 

Делегат и контекстные ссылки на расширение в другом файл. С этим кодом иногда это работает, а иногда нет. Я меняю порядок, снова запускаю приложение, и он находится в совершенно другом порядке, который я не могу понять. Особенно, когда я перемещаю сразу несколько строк. И если я напечатаю атрибут «позиция» каждого объекта на консоли, я вижу, что они действительно не обновляются должным образом. Но почему нет?

Что я делаю неправильно? Что было бы лучше?

Спасибо заранее,

Daniel


Edit:

Хорошо, вот рабочий код:

func initializeFetchedResultsController() { 
    let request = NSFetchRequest(entityName: "Book") 
    let sortDescriptor = NSSortDescriptor(key: "position", ascending: true) 
    request.sortDescriptors = [sortDescriptor] 

    self.fetchedResultsController = NSFetchedResultsController(fetchRequest: request, managedObjectContext: context, sectionNameKeyPath: nil, cacheName: nil) 
    self.fetchedResultsController.delegate = self 

    do { 
     try self.fetchedResultsController.performFetch() 
    } catch { 
     fatalError("Failed to initialize FetchedResultsController: \(error)") 
    } 
} 

// Override to support rearranging the table view. 
override func tableView(tableView: UITableView, moveRowAtIndexPath fromIndexPath: NSIndexPath, toIndexPath: NSIndexPath) { 

    initializeFetchedResultsController() 
    var objects = self.fetchedResultsController.fetchedObjects! as! [ObjectClass] 

    self.fetchedResultsController.delegate = nil 

    let object = objects[fromIndexPath.row] 
    objects.removeAtIndex(fromIndexPath.row) 
    objects.insert(object, atIndex: toIndexPath.row) 

    var i = 0 
    for object in objects { 
     object.position = i++ 
    } 

    try! context.save() 

    self.fetchedResultsController.delegate = self 
} 

Хитрость заключается в том, что функция initializeFetchedResultsController, кроме того, viewDidLoad, где у меня было это, должен быть повторен внутри бита moveRowAtIndexPath. Кроме того, функция инициализации и объявление массива должны быть оба перед установкой делегата FRC на нуль (очевидно, но это легко пропустить).

ответ

3

Вы не должны редактировать books, она не принадлежит вам и эффективно личные данные. Вместо этого вы должны просто обновлять объекты, которые перемещаются, чтобы изменить значение position. Если вы сделаете это, используя переупорядочение массива, как в вашей текущей логике, вы должны создать новую изменяемую копию массива, предоставленную FRC. Вы также должны устанавливать новые значения для позиции как NSNumber экземпляров.

+0

Умм, я думал, что это уже измененная копия. Как мне это сделать? Извините за глупые вопросы, это моя первая попытка программирования вообще. – dbmrq

+0

Это не совсем ясно из документов, в obj-c он неизменен, в быстрой он вполне может быть копией, которую вы можете редактировать. Вероятно, проблема 'NSNumber' - проблема. – Wain

+0

Ну, для этого я должен просто использовать «i as NSNumber»? Я пробовал это, xcode не жалуется, но он все равно не работает. :( – dbmrq

0

Необходимо использовать sortDescriptor, после чего информация, полученная вами от запроса выборки, уже отсортирована. Это, как я реализовать свои fetchRequests:

lazy var connectionsFetchRequest: NSFetchRequest = { 
    var request = NSFetchRequest(entityName: "Connection") 
    let predicate = NSPredicate(format: "%K == %@", argumentArray: ["user", UserManager.SharedInstance.user!]) 
    request.sortDescriptors = [NSSortDescriptor(key: "firstName", ascending: true)] 
    request.predicate = predicate 
    return request 
}() 
+0

Я делаю это ... Я обновлю вопрос с помощью кода. – dbmrq

+0

Пожалуйста, показать больше кода. Нам нужно знать, что вы уже делаете. Пожалуйста, разместите свой файл fetchRequest. – Swinny89

+1

Вот оно, спасибо за помощь! – dbmrq

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