预取并构建整个集合的单元格View

时间:2019-04-13 17:14:21

标签: ios swift tableview collectionview

我有一个标签数组。我的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的prefetch方法中构造单元格,但是却无济于事。

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 :(得分:0)

单元格已出队,您应该使模型具有所有更改的最新信息,并反映到单元格(如果存在),因为不可见的单元格为nil,您需要

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

guard编写代码,而无需在{ }中插入以下代码

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

如果该单元格存在,它将被更新;否则,它将在再次出现时从模型中获得最新更改