Предварительная выборка и сборка ячеек для всей коллекции. - PullRequest
0 голосов
/ 13 апреля 2019

У меня есть массив тегов.Мой collectionView показывает токен тега для каждого тега.Я разрешаю пользователям искать заголовок каждого тега, и если в массиве есть совпадение, токен выбирается и перемещается в индекс 0 массива (и indexPath).Это все работает нормально, но я сталкиваюсь с падением, когда пользователь находит соответствие для токена, который еще не отображается в collectionView (в случае длинных массивов тегов).

Я нашел примеры для предварительной выборки данных (например, изображений) для collectionViews, но ничего, что позволяло бы мне строить ячейки заранее.

Это мой метод, который ищет совпадения в массиве на основе ввода пользователя.Я получаю аварийное завершение в строке, где я создаю ячейку

let cell = ....

аварийное завершение:

«Поток 1: Неустранимая ошибка: неожиданно обнаружен ноль при развертывании необязательного значения»,

означает, что ячейка просто еще не существует.

func insertNewTag() {
    guard let tagInput = tagTextField.text else { return }

    if let match = myTags.first(where: { $0.value == tagInput.lowercased() }) {
        print("Found a match")
        guard let indexOfMatch = myTags.index(where: {$0.value == match.value}) else { return }
        let indexPathOfMatch = IndexPath(item: indexOfMatch, section: 0)
        let cell = tagsCollectionView.cellForItem(at: indexPathOfMatch) as! AddTagCell
        if cell.cellIsSelected == true {
            print("Already selected, don't append")
        } else {
            cell.cellIsSelected = true
            selectedTags.append(match)
        }
        myTags.remove(at: indexOfMatch)
        myTags.insert(match, at: 0)
        let newIndexPath = IndexPath(item: 0, section: 0)
        tagsCollectionView.moveItem(at: indexPathOfMatch, to: newIndexPath)
    } else {
        print("No match, creating new tag")
        let dictionary = ["label": tagInput, "value": tagInput.lowercased()]
        let newTag = MyTag(uid: nil, dictionary: dictionary)
        myTags.insert(newTag, at: 0)
        let indexPath = IndexPath(item: 0, section: 0)
        tagsCollectionView.insertItems(at: [indexPath])
        let cell = tagsCollectionView.cellForItem(at: indexPath) as! AddTagCell
        cell.cellIsSelected = true
        selectedTags.append(newTag)
    }

    tagTextField.text = nil
}

Я пытался сконструировать ячейки в методе предварительной выборки collectionView, но это ни к чему не привело.

func collectionView(_ collectionView: UICollectionView, prefetchItemsAt indexPaths: [IndexPath]) {
    print("Prefetch: \(indexPaths)")
    for indexPath in indexPaths {
        let cell = tagsCollectionView.dequeueReusableCell(withReuseIdentifier: "AddTagCell", for: indexPath) as! AddTagCell
        let tag = myTags[indexPath.row]
        cell.myTag = tag
        if let indices = selectedTagIndices {
            if indices.first(where: { $0 == indexPath.row }) != nil {
                cell.cellIsSelected = true
            }
        }
    }
}

Я очень благодарен за любые подсказки, как лучше всего решить эту проблему !!

1 Ответ

0 голосов
/ 13 апреля 2019

Ячейки сняты с производства, ваша модель должна быть обновлена ​​со всеми изменениями и отражать их в ячейках, если они есть, так как ячейка, которая не видна, равна нулю, вам нужно

if let cell = tagsCollectionView.cellForItem(at: indexPathOfMatch) as? AddTagCell {
 ////
}

ИЛИ guard для написания кода без вставки приведенного ниже кода в { }

guard let cell = tagsCollectionView.cellForItem(at: indexPathOfMatch) as? AddTagCell else { return }

Если ячейка существует, она будет обновлена, в противном случае она получит последние изменения от модели при повторном появлении

...