#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 не более чем внизу, чтобы при необходимости обновить ячейку, если она существует