Unable to reload only the selected cell

Multi tool use
Unable to reload only the selected cell
I want to reload only the selected cell in particular when tapping a picture in a cell.But i got the error cannot convert value of type 'IndexPath.Type' to expected argument type 'IndexPath'in this line: loadPostsValue(indexPath: IndexPath)
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let indexPath = self.collectionView.indexPathsForSelectedItems
print(indexPath)
loadPostsValue(indexPath: IndexPath)
}
func loadPostsValue(indexPath: IndexPath) {
posts.removeAll()
let ref = Database.database().reference()
ref.child("posts").observe(.childAdded) { (snapshot: DataSnapshot) in
if let dict = snapshot.value as? [String: Any] {
guard let titleText = dict["title"] as? String else{return}
let locationDetails = dict["location"] as! String
let captionText = dict["caption"] as! String
let photoUrlString = dict["photoUrl"] as! String
let priceText = dict["price"] as! String
let categoryText = dict["category"] as! String
let usernameLabel = dict["username"] as! String
let profileImageURL = dict["pic"] as! String
let heartInt = dict["heart"] as! Int
let timestampString = dict["timestamp"] as! String
let post = Post(titleText: titleText, captionText: captionText, locationDetails: locationDetails, photoUrlString: photoUrlString, priceText: priceText,categoryText: categoryText, usernameLabel: usernameLabel, profileImageURL: profileImageURL, heartInt: heartInt, timestampString: timestampString)
self.posts.append(post)
print(self.posts)
self.collectionView.reloadItems(at: [indexPath])
}
}
}
indexPath
IndexPath
I think you are passing the IndexPath class object instead of passing the reference indexPath.
– Karthick Ramesh
Jul 1 at 4:05
But i tried passing IndexPath in my code. I was getting error "Cannot convert value of type 'IndexPath.Type' to expected argument type 'IndexPath'". May be you should clean the xcode CMD+SHIFT+K and then re build the code to get the compilation error, i think.
– Karthick Ramesh
Jul 1 at 4:11
1 Answer
1
You should provide the required indexPath
as below,
indexPath
if let indexPath = self.collectionView.indexPathsForSelectedItems?.first {
print(indexPath)
loadPostsValue(indexPath: indexPath)
}
Currently you are not passing an object of IndexPath
instead you are passing its Type
which compiler
is complaining about. Also indexPathsForSelectedItems
is an array
of all selected item so you should retrieve the first indexPath
if your collectionView
's multiple selection is off.
IndexPath
Type
compiler
indexPathsForSelectedItems
array
indexPath
collectionView
Edit I think a straightforward way is to not use indexPathsForSelectedItems
when you already have the selected indexPath
from the delegate method itself. You can simply pass that as below,
indexPathsForSelectedItems
indexPath
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
loadPostsValue(indexPath: indexPath)
}
As you mentioned in the comments, i think if you just want to update the likes count, you can do it as below,
func loadPostsValue(indexPath: IndexPath) {
let ref = Database.database().reference()
ref.child("posts").observe(.childAdded) { (snapshot: DataSnapshot) in
if let dict = snapshot.value as? [String: Any] {
guard let titleText = dict["title"] as? String else{ return }
let post = self.posts[indexPath.row]
post.heartInt = dict["heart"] as! Int
self.collectionView.reloadItems(at: [indexPath])
}
}
}
I am getting this : Invalid update: invalid number of items in section 0. The number of items contained in an existing section after the update (1) must be equal to the number of items contained in that section before the update (2), plus or minus the number of items inserted or deleted from that section (1 inserted, 1 deleted) and plus or minus the number of items moved into or out of that section (0 moved in, 0 moved out).' *** First throw call stack:
– Lionel Tan
Jul 1 at 4:37
@LionelTan as you are manipulating the
dataSource
(self.posts.append(post)
) of the collectionView
so you might have to insert that item first before reload. You can verify your code by commenting out that line where you are appending a new post.– Kamran
Jul 1 at 5:32
dataSource
self.posts.append(post)
collectionView
When a user tapped on the like button of a post, the number of likes will increase.As i would like only that specific post to be reloaded or better still would be just the number of likes of that post.In the database, the number of likes would change alr,but just that i am not sure how do i just reload that portion.The listener of firebase is asynchronous which means that i would delay for 0.1 seconds using a completion handler before i load the post.But i am not sure how to load just a post or better still just the number of likes, instead of all the posts.
– Lionel Tan
Jul 1 at 7:14
In that case, you should just update the likes count in your model and reload that cell the same way you are doing. I believe you should not be doing
posts.removeAll()
and self.posts.append(post)
.– Kamran
Jul 1 at 7:19
posts.removeAll()
self.posts.append(post)
In the
observe
callback you should get the old post object and update its properties with new data. I will put this in the answer. I think that might solve your issue.– Kamran
Jul 1 at 7:21
observe
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
You want
indexPath
- small i, notIndexPath
– Paulw11
Jul 1 at 4:01