I was seeing a code where a collection view is made and we can mark some items as favorite. Also there is a filter button on top if we select that only favorite items will be visible.
Now is favorite filter is applied, then any random item is unfavourated then from the collection view, the last item disappears (which is wrong, but the bussiness logic going on is right I have tested multiple times using breakpoints) and now if I go back and come to favorites page again then the wrong item which disappeared is in the list and the correct item which was unfavorited is not present because the businesses logic was right and the data source has correct elements so the collection view made is correct (what i think).
Now I guess after tapping favorite button something wrong is hapenning, that the collection view reloading has some problem.
Also second question is is always mandatory to call
collectionView.reloadData()
and
collectionView.reloadItems(at: [IndexPath(item: index, section: 0)])
in main thread using DispatchQueue.main.async
I am new to swift, can you help out what could be the case that the reload is happening is wrong but in data source correct element is removed.
Problem gif: View Here
I was not able to add in this post
UPDATE: added code snippets:
On tapping heart symbol this function is invoked:
func editFavouriteChannelList(with viewModel: MyChannelViewModel?, index: Int) {
guard var viewModel = viewModel,
viewModel.isFavouriteEnabled,
var channel = viewModel.channels?[safe: index],
!channel.state.isChangingStateInProgress() else {
return
}
// Some working
// Calls updateCell fn with same viewModel but updated channel state
self.updateCell(with: viewModel, channelCellModel: channel)
// This makes API call then again we call on it's success updateCell fn with viewModel have removed that updated channel
interactor.editFavouriteChannelList(with: channel, isMarkingFavourite: isMarkingFavourite)
}
This presenter's updateCell
is called twice,
first when only channelCellModel
is updated
and second time after making an API call that time viewModel
will have that channel removed from it.
In presenter:
private func updateCell(with viewModel: MyChannelViewModel, channelCellModel: MyChannelCellModel) {
DispatchQueue.main.async { [weak self] in
self.interface?.updateCell(with: viewModel, channelCellModel: channelCellModel)
}
}
In ViewController:
func updateCell(with viewModel: MyChannelViewModel, channelCellModel: MyChannelCellModel) {
if myChannelVM?.channels?.count != viewModel.channels?.count {
self.myChannelVM = viewModel
collectionView.reloadData()
} else {
guard let index = myChannelVM?.channels?.firstIndex(of: channelCellModel) else {
return
}
myChannelVM?.channels?[index] = channelCellModel
print(" Like: updateCell local : \(myChannelVM?.channels?[index])")
collectionView.reloadItems(at: [indexPath])
}
}
In View Controller logic going on is like this first call to updateCell
is made where viewModel
is same as myChannelVM
but channelCellModel
is a channel with updated state.
Then second time call to updateCell
is made where viewModel
is same as myChannelVM
but not having that channel which was earlier marked unfavorite
.
Now if I remove collectionView.reloadItems(at: [indexPath])
from else block and use collectionView.reloadData()
in place of it then collection view updates correctly otherwise not.
So updateCell(at:)
is interfereing with reloadData()
of when made in next call.
So there is issue like Why is a call to reloadItems(at:) stopping/breaking call to reloadData() in Collection View?
What is the reason for this in my case?