简体   繁体   English

UICollectionView在reloadData上崩溃

[英]UICollectionView Crash on reloadData

UICollectionview is loaded with simple cells and there is a simple int variable for calculating the number of items in the section. UICollectionview加载了简单单元格,并且有一个简单的int变量用于计算该部分中的项目数。

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return viewCount
}

When the value of viewCount (initially at 45) is changed to a lower number (say 12) the app crashes. 当viewCount(最初为45)的值更改为较低的数字(例如12)时,应用程序崩溃。

This is error message to update the item count: 这是更新项目计数的错误消息:

 *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'UICollectionView received layout attributes for a cell with an index path that does not exist: <NSIndexPath: 0x17402fbe0> {length = 2, path = 0 - 12}'

I tried reloading data and invalidating the cache as well as said here . 我尝试重新加载数据并使缓存失效,并在此处说。 This didn't help. 这没有用。 I also tried reloading the indexSet before invalidating the cache. 我也尝试在使缓存失效之前重新加载indexSet。 That didn't help either. 这也没有帮助。

    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        if textField == countTextField {
            viewCount = Int(textField.text!)!
            textField.resignFirstResponder()
            let indexSet = IndexSet(integer: 0)

//            collectionView.reloadSections(indexSet)
            collectionView.reloadData()
            collectionView.collectionViewLayout.invalidateLayout()
        }

        return true
    }

I use 2 custom UICollectinViewLayout and I also set shouldInvalidateLayout to be true. 我使用2个自定义UICollectinViewLayout ,我也将shouldInvalidateLayout设置为true。 Any help? 有帮助吗?

Update 更新

func numberOfSections(in collectionView: UICollectionView) -> Int {
        return 1
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "DemoCell", for: indexPath) as! DemoCollectionViewCell
        cell.indexLabel.text = "\(indexPath.item + 1)"

        return cell
    }

    @IBAction func showLayout1(_ sender: Any) {
        currentLayout = DemoACollectionViewLayout()
        animateLayout()
    }

    @IBAction func showLayout2(_ sender: Any) {
        currentLayout = DemoBCollectionViewLayout()
        animateLayout()
    }

    func animateLayout() {
        UIView.animate(withDuration: 0.3) { [weak self] value in
            guard let `self` = self else { return }
            self.collectionView.collectionViewLayout.invalidateLayout()
            self.collectionView.collectionViewLayout = self.currentLayout!
        }
    }

Here is the sample project. 这是示例项目。

Update : I have updated to use an dataObject to reload the UICollectionView but the cache in UICollectionViewLayout is not being cleared when I invalidate. 更新 :我已更新使用dataObject重新加载UICollectionView但是当我无效时,UICollectionViewLayout中的缓存未被清除。

The cache must be cleared when the number of items for the collectionView has changed. 当collectionView的项目数已更改时,必须清除缓存。

guard let views = collectionView?.numberOfItems(inSection: 0)
            else {
    cache.removeAll()
    return
}

if views != cache.count {
    cache.removeAll()
}

if cache.isEmpty { 
   //Layout attributes
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM