Предварительная выборка и построение ячеек для всего CollectionView

#ios #swift #tableview #collectionview

#iOS #swift #просмотр таблицы #collectionview

Вопрос:

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

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

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

 let cell = ....
 

Крушение — это:

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

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

 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:

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

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

ИЛИ guard написать код, не вставляя приведенный ниже код в { }

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

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

Комментарии:

1. Хм, поэтому, к сожалению, это приведет к игнорированию моего кода для выбора ячейки и перемещения ее вперед, поскольку ячейка еще не существует. Я надеялся, что смогу выделить ячейки, которые не видны.

2. переместите код, который обновляет модель, вверх и оставьте if let или guard не более чем внизу, чтобы при необходимости обновить ячейку, если она существует