CollectionView.reloadData () выводит ячейки в неправильном порядке - PullRequest
0 голосов
/ 19 сентября 2018

Я работаю над приложением, которое требует синхронизации с сервером после входа в систему, чтобы получить все действия, созданные пользователем и сохраненные на сервере.В настоящее время, когда пользователь регистрируется в функции getActivity(), которая делает запрос API и возвращает ответ, который затем обрабатывается.

Скажем, у пользователя есть 4 действия, сохраненные на сервере в этом порядке (порядок определенк моменту создания / сохранения действия);

  • Тест
  • Боб
  • cvb
  • Тестирование

глядя на JSONHandler.getActivityResponse, кажется, что результаты в правильном порядке.Если запрос был успешным, на домашней странице, где должны отображаться эти действия, я в настоящее время перебираю их так:

WebAPIHandler.shared.getActivityRequest(completion:
        {
            success, results in DispatchQueue.main.async {
                    if(success)
                    {
                        for _ in (results)!
                        {
                            guard let managedObjectContext = self.managedObjectContext else { return }

                            let activity = Activity(context: managedObjectContext)

                            activity.name = results![WebAPIHandler.shared.idCount].name
                            print("activity name is - \(activity.name)")
                            WebAPIHandler.shared.idCount += 1
                        }
                    }

И вывод в цикле for также выводится в ожидаемом порядке;

activity name is - Optional("Test")
activity name is - Optional("Bob")
activity name is - Optional("cvb")
activity name is - Optional("Testing")

Затем CollectionView вставляет новые ячейки, но, по-видимому, в неправильном порядке.Я использую раскладку карусели на домашней странице, и, например, объект 'cvb' появляется первым в списке, а 'bob' третий в списке.Я использую следующее

 func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?)
{
    switch (type)
    {
    case .insert:

        if var indexPath = newIndexPath
        {
//                    var itemCount = 0
//                    var arrayWithIndexPaths: [IndexPath] = []
//                
//                    for _ in 0..<(WebAPIHandler.shared.idCount)
//                    {
//                        itemCount += 1
//                        
//                        arrayWithIndexPaths.append(IndexPath(item: itemCount - 1, section: 0))
//                        print("itemCount = \(itemCount)")
//                }

            print("Insert object")
//                walkThroughCollectionView.insertItems(at: arrayWithIndexPaths)
            walkThroughCollectionView.reloadData()

    }

Вы можете понять, почему я пытался использовать collectionView.insertItems (), но это вызвало бы сообщение об ошибке:

Invalid update: invalid number of items in section 0.  The number of items contained in an existing section after the update (4) must be equal to the number of items contained in that section before the update (4), plus or minus the number of items inserted or deleted from that section (4 inserted, 0 deleted)

Я видел многоиз других ответов, в которых упоминается, как reloadData() решит проблему, но я застрял на этом.Я пользуюсь swift уже несколько месяцев, и это был первый раз, когда я действительно в растерянности.Я также понял, что порядок отображения в карусели также отличается от отдельного viewController, которому передаются те же данные.Я просто не знаю, почему результаты возвращаются в правильном порядке, но затем отображаются в неправильном порядке.Есть ли способ сортировки данных в collectionView после вызова reloadData() или я смотрю на это под неправильным углом?

Любая помощь будет высоко ценится, ура!

1 Ответ

0 голосов
/ 19 сентября 2018

Порядок представления коллекции определяется дескрипторами сортировки контроллера извлеченных результатов.

Обычно рабочий процесс вставки нового NSManagedObject равен

  • Вставить новый объект в контекст управляемого объекта.
  • Сохранить контекст.Это вызывает методы делегата controllerWillChangeContent, controller(:didChange:at: и т. Д.
  • В controller(:didChange:at: вставьте ячейку в представление коллекции с помощью insertItems(at:, больше ничего.Не вызывайте reloadData() в этом методе.
...