UICollectionView 接收到具有不存在索引路径的单元格的布局属性

Posted

技术标签:

【中文标题】UICollectionView 接收到具有不存在索引路径的单元格的布局属性【英文标题】:UICollectionView received layout attributes for a cell with an index path that does not exist 【发布时间】:2017-10-24 06:41:58 【问题描述】:

我使用了两个集合视图,名称分别为 cltnEditscltnTools,我默认显示 cltnTools。当用户单击cltnTools 的任何项目时,将出现cltnEdits 集合视图,否则它将被隐藏。有一个带有cltnEdits 的取消按钮,每当用户单击该取消按钮时,cltnEdits 就会消失(隐藏)并出现cltnTools

我的两个 Collection 视图都在 UIStackView 中

从集合视图中选择名称为 cltnTools 的元素时出现以下错误。

我已尝试以下代码来解决此错误,但它对我不起作用

            cltnEdits.reloadData()
            cltnEdits.collectionViewLayout.invalidateLayout()
            cltnEdits.layoutSubviews()

            cltnTools.reloadData()
            cltnTools.collectionViewLayout.invalidateLayout()
            cltnTools.layoutSubviews()

也试过了

override func viewWillLayoutSubviews() 
    super.viewWillLayoutSubviews()

    cltnEdits.collectionViewLayout.invalidateLayout()

并添加了这个 UICollectionViewDelegateFlowLayout 代表

func shouldInvalidateLayout(forBoundsChange newBounds: CGRect) -> Bool 
    return true

以下是 cltnTools

didSelect 方法
   func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) 

    if collectionView == cltnTools 

        selectedItem.push(item: "CltnTools")

        switch indexPath.row 

        case 0:

            //Edits

            arrImage = arrEditToolsImage
            arrText = arrEditToolsText

            selectedItem.push(item: arrMainToolsText[indexPath.row])

            viewCrop.image = imgImage.image

            cltnEdits.reloadData()
            cltnEdits.collectionViewLayout.invalidateLayout()
            cltnEdits.layoutSubviews()

            toolsToEdits()

            break

        case 1:

            //Effect

            selectedItem.push(item: arrMainToolsText[indexPath.row])

            arrImage = arrEffectToolsImage
            arrText = arrEffectToolsText

            cltnEdits.reloadData()
            cltnEdits.collectionViewLayout.invalidateLayout()
            cltnEdits.layoutSubviews()

            toolsToEdits()

            break

        case 2:

            //Colors

            selectedItem.push(item: arrMainToolsText[indexPath.row])

            arrImage = arrColorToolsImage

            cltnEdits.reloadData()
            cltnEdits.collectionViewLayout.invalidateLayout()
            cltnEdits.layoutSubviews()

            toolsToEdits()

            break

        case 3:

            //Text

            selectedItem.push(item: arrMainToolsText[indexPath.row])

            arrImage = arrTextToolsImage
            arrText = arrTextToolsText

            imgImage.addLabel()

            //Modify the Label
            imgImage.textColor = UIColor.black
            imgImage.textAlpha = 1
            imgImage.currentlyEditingLabel.closeView!.image = #imageLiteral(resourceName: "Delete")
            imgImage.currentlyEditingLabel.rotateView?.image = #imageLiteral(resourceName: "Resize")
            imgImage.currentlyEditingLabel.border?.strokeColor = UIColor.black.cgColor

            cltnEdits.reloadData()
            cltnEdits.collectionViewLayout.invalidateLayout()
            cltnEdits.layoutSubviews()

            toolsToEdits()


            break

        case 4:

            //Frame

            selectedItem.push(item: arrMainToolsText[indexPath.row])

            print("Frame \(arrFrameToolsImage.count)")

            arrImage = arrFrameToolsImage

            cltnEdits.reloadData()
            cltnEdits.collectionViewLayout.invalidateLayout()
            cltnEdits.layoutSubviews()

            toolsToEdits()

            break

        case 5:

            //Goodies

            selectedItem.push(item: arrMainToolsText[indexPath.row])

            arrImage = arrGoodiesToolsImage

            print("Goodies \(arrGoodiesToolsImage.count)")

            cltnEdits.reloadData()
            cltnEdits.collectionViewLayout.invalidateLayout()
            cltnEdits.layoutSubviews()

            toolsToEdits()

            break

        default:
            break

        

    

如何解决我的错误?有人请帮忙!

注意:在将其标记为重复之前,请检查我的代码,我已尝试在堆栈上提出的其他问题中给出的所有解决方案。

【问题讨论】:

看看这个。我希望它相当相关。 ***.com/questions/44199722/… 您在 cltnTools 的 didSelect 方法中的代码是什么?? @Swift_Guru 检查我更新的代码。 错误是给定索引路径上没有单元格。因此,请确保您的数据源为单元格提供正确的输入。并尝试一件事,首先使布局无效,然后重新加载collectionview。 【参考方案1】:

尝试交换reloadData()invalidateLayout(),另外不要直接调用layoutSubviews(见docs)

cltnEdits.collectionViewLayout.invalidateLayout()
cltnEdits.reloadData()
cltnEdits.setNeedsLayout()
cltnEdits.layoutIfNeeded()


cltnTools.collectionViewLayout.invalidateLayout()
cltnTools.reloadData()
cltnTools.setNeedsLayout()
cltnTools.layoutIfNeeded()

【讨论】:

您好,我们目前正在调查类似的问题。你能解释一下为什么应该在 reloadData() 之前而不是之后调用 invalidateLayout() 吗?如果您已经在调用invalidateLayout(),那么setNeedsLayout()layoutIfNeeded() 是否必要?

以上是关于UICollectionView 接收到具有不存在索引路径的单元格的布局属性的主要内容,如果未能解决你的问题,请参考以下文章

UICollectionView 收到具有不存在索引路径的单元格的布局属性

具有单元格间距的 UICollectionView 存在滚动问题

UICollectionView 不刷新

具有网络数据的 UICollectionView 在与交互之前不显示单元格

UICollectionView:激活、滚动到并将第一响应者分配到远处的单元格

滚动时 Uicollectionview 不更新标题