Reputation: 456
Its getting called in viewDidLoad
, after fetching the data used.
After some print debugging it looks like it calls all the appropriate delegeate methods, if no data is changed. If there has been some data changed, cellForItemAt
does not get called.
Reloading the whole section works fine. But gives me an unwanted animation. Tried disabling UIView
animation before, and enabling after reloading section, but still gives me a little animation.
collectionView.reloadSections(IndexSet(integer: 0))
Here is my current situation, when using reloadData()
The UICollectionViewController is a part of a TabBarController. I'm using custom UICollectionViewCells. The data is loaded from CoreData.
First time opening the tab, its works fine. After updating the favorites item in another tab, and returning to this collectionView, its not updated. But if i select another tab, and go back to this one, its updated.
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
}
Console Print/Log
Starting the app, going to the CollectionView tab where there are no favorites:
Load Favorites
Get number of section, 0
Get number of section, 0
Reload CollectionView
Get number of section, 0
Switching tab, and adding and setting an Item object's favorite to true, then heading back to the CollectionView tab:
Load Favorites
Favorites count: 1
Reload CollectionView
Get number of section, 1
The datamodel has 1 item, reloading CollectonView, cellForRowAtIndex not called?
Selecting another tab, random which, then heading back to the CollectionView tab, without changing any data.
Load Favorites
Favorites count: 1
Reload CollectionView
Get number of section, 1
Get cell
Now my Item shows up in the list. You can see from the Get Cell that cellForItemAt
is called aswell. Nothing has changed between these last two loggings, just clicked back/fourth on the tabs one time.
Forgot to mention, but this code IS working fine in the simulator.
On a read device its just not giving me any error, just not showing the cell (or calling the cellForItemAt
)
Upvotes: 12
Views: 20615
Reputation: 5806
Some naive/jr guy did this
var array = realdatasource
mod array
reloadData()
needless to say it did not work due to copy on write modifying temp data and those changes were dumped on the floor.
Upvotes: 0
Reputation: 802
I had the same issue. I was updating the height of the UICollectionView based on the content and reloadData() stops working when you set the height of the collection view to zero. After setting a minimum height. reloadData() was working as expected.
Upvotes: 0
Reputation: 1221
i was facing also this kind of issue so finally i am able to solved using this line of code
[self.collectionView reloadData];
[self.collectionView reloadItemsAtIndexPaths:@[[NSIndexPath indexPathWithIndex:0]]];
Upvotes: 0
Reputation: 21
var paths: [IndexPath] = []
if !data.isEmpty {
for i in 0...salesArray.count - 1 {
paths.append(IndexPath(item: i, section: 0))
}
collectionView.reloadData()
collectionView.reloadItems(at: paths)
}
This is the code helped me, for solving this kind of issue.
Upvotes: 2
Reputation: 429
Ok, maybe I can help someone =)
I do this:
Then after load data call DispatchQueue.main.async like this
DispatchQueue.main.async {
self.pointNews = pointNews
}
In self.pointNews didSet I try to do collectionView.reloadData(), but it work only, if I call DispatchQueue.main.async in didSet
DispatchQueue.main.async {
self.collectionView.reloadData()
}
Upvotes: 4
Reputation: 773
in my case, my collectionview was in a stackview, i didnt make any constraints, when i added the necessary constraints it worked.
Just check collectionview's constraints.
Upvotes: 5
Reputation: 379
I faced the same problem with self resizing cells and above solution works as well but collection view scroll position resets and goes to top. Below solution helps to retain your scroll position.
collectionView.reloadData()
let context = collectionView.collectionViewLayout.invalidationContext(forBoundsChange: collectionView.bounds)
context.contentOffsetAdjustment = CGPoint.zero
collectionView.collectionViewLayout.invalidateLayout(with: context)
collectionView.layoutSubviews()
Upvotes: 0
Reputation: 456
After some more debugging i got an error when the items got reduced (instead of increasing like i've tried above).
UICollectionView received layout attributes for a cell with an index path that does not exist
This led med to iOS 10 bug: UICollectionView received layout attributes for a cell with an index path that does not exist
collectionView!.reloadData()
collectionView!.collectionViewLayout.invalidateLayout()
collectionView!.layoutSubviews()
This solved my problem.
I am using autoresizing cells, but i guess this does not explain why cellForItemAt
did not get called.
Upvotes: 12
Reputation: 131398
Post your code.
One possibility is that you are using `URLSession and trying to tell your collection view to update from the it's delegate method/completion closure, not realizing that that code is run on a background thread and you can't do UI calls from background threads.
Upvotes: 0