UICollectionView reloadData不起作用

Esp*_*irk 5 ios uicollectionview swift

viewDidLoad在获取使用的数据后,将其调用。如果未更改任何数据,则在进行一些打印调试后,它似乎将调用所有适当的delegeate方法。如果某些数据已更改,cellForItemAt则不会调用。

重新加载整个部分效果很好。但是给我一个不需要的动画。尝试UIView在重新加载之前禁用动画,并在重新加载之后启用动画,但是仍然给了我一点动画。

collectionView.reloadSections(IndexSet(integer: 0)) 
Run Code Online (Sandbox Code Playgroud)

这是我当前的情况,当使用reloadData()时

UICollectionViewController是TabBarController的一部分。我正在使用自定义UICollectionViewCells。数据是从CoreData加载的。

第一次打开标签页,它可以正常工作。在另一个选项卡中更新收藏夹项并返回此collectionView之后,其未更新。但是,如果我选择另一个选项卡,然后返回到该选项卡,则它已更新。

var favorites = [Item]()


override func viewWillAppear(_ animated: Bool) {

    collectionView!.register(UINib.init(nibName: reuseIdentifier, bundle: nil), forCellWithReuseIdentifier: reuseIdentifier)

    if let flowLayout = collectionView!.collectionViewLayout as? UICollectionViewFlowLayout {
        flowLayout.estimatedItemSize = CGSize(width: 1,height: 1)
    }

    loadFavorites()

}


func loadFavorites() {

    do {
        print("Load Favorites")

        let fetch: NSFetchRequest = Item.fetchRequest()
        let predicate = NSPredicate(format: "favorite == %@", NSNumber(value: true))
        fetch.predicate = predicate
        favorites = try managedObjectContext.fetch(fetch)

        if favorites.count > 0 {
            print("Favorites count: \(favorites.count)")
            notification?.removeFromSuperview()
        } else {
            showEmptyFavoritesNotification()
        }

        print("Reload CollectionView")

        collectionView!.reloadData(


    } catch {
        print("Fetching Sections from Core Data failed")
    }
}


override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {

    print("Get number of section, \(favorites.count)")
    if favorites.count > 0 {
        return favorites.count
    } else {
        return 0
    }
}

override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    print("Get cell")

    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath) as! SubMenuCell

    let menuItem = favorites[indexPath.row]

    cell.title = menuItem.title
    cell.subtitle = menuItem.subtitle

    return cell
}
Run Code Online (Sandbox Code Playgroud)

控制台打印/日志

启动应用程序,转到没有收藏夹的CollectionView选项卡:

Load Favorites
Get number of section, 0
Get number of section, 0
Reload CollectionView
Get number of section, 0
Run Code Online (Sandbox Code Playgroud)

切换选项卡,并将Item对象的收藏夹添加并设置为true,然后返回到CollectionView选项卡:

Load Favorites
Favorites count: 1
Reload CollectionView
Get number of section, 1

The datamodel has 1 item, reloading CollectonView, cellForRowAtIndex not called?
Run Code Online (Sandbox Code Playgroud)

选择另一个选项卡,随机选择,然后返回到CollectionView选项卡,而不更改任何数据。

Load Favorites
Favorites count: 1
Reload CollectionView
Get number of section, 1
Get cell
Run Code Online (Sandbox Code Playgroud)

现在,我的项目显示在列表中。您也可以从cellForItemAt称为“获取单元格”的位置看到。在最后两个日志之间没有任何变化,只需单击一次或四次单击选项卡即可。

忘记了,但是此代码在模拟器中可以正常工作。在读取设备上,它只是没有给我任何错误,只是没有显示单元格(或调用cellForItemAt

Esp*_*irk 10

经过更多调试后,当项目减少时出现错误(而不是像我上面尝试的那样增加)。

UICollectionView received layout attributes for a cell with an index path that does not exist
Run Code Online (Sandbox Code Playgroud)

这导致了iOS 10 错误:UICollectionView 收到了具有不存在索引路径的单元格的布局属性

collectionView!.reloadData()
collectionView!.collectionViewLayout.invalidateLayout()
collectionView!.layoutSubviews()
Run Code Online (Sandbox Code Playgroud)

这解决了我的问题。

我正在使用自动调整单元格,但我想这并不能解释为什么cellForItemAt没有被调用。


Dun*_*n C 0

发布您的代码。

一种可能性是您正在使用 URLSession 并试图告诉您的集合视图从它的委托方法/完成闭包进行更新,但没有意识到该代码是在后台线程上运行的,并且您无法从后台线程进行 UI 调用。