Reputation: 21
When I run the code below, it sometimes make changes for other cells than the one its actually ment for. It sets votes that is from another post. Any idea why ?
show/hide votesView is just votesView.isHidden = true/false for the views enable/disable Btns is just btns.isEnabled = true/false for the Buttons. Both if these works fine.
This is my code for PostCell:
override func awakeFromNib() {
super.awakeFromNib()
hideVoteViews()
let ref = DataService.ds.REF_USER_CURRENT
let likeRef = ref.child("likes")
likeRef.observeSingleEvent(of: .value) { (snapshot) in
if snapshot.hasChild(self.post.postKey){
self.setVotesLbl()
self.showVoteViews()
self.disableBtns()
} else {
self.hideVoteViews()
self.enableBtns()
}
}
}
setVotesLbl function:
func setVotesLbl(){
if let votes = self.post?.altAVotes{
self.altAVotesLbl.text = "\(votes)"
}
if let votes = self.post?.altBVotes{
self.altBVotesLbl.text = "\(votes)"
}
if let votes = self.post?.altCVotes{
self.altCVotesLbl.text = "\(votes)"
}
if let votes = self.post?.altDVotes{
self.altDVotesLbl.text = "\(votes)"
}
}
Upvotes: 0
Views: 78
Reputation: 341
Because of re-usability of the UITableview "awakeFromNib()" of the PostCell would not called every time for the "func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell". To achieve this you have to Call:
func getCellData()
{
hideVoteViews()
let ref = DataService.ds.REF_USER_CURRENT
let likeRef = ref.child("likes")
likeRef.observeSingleEvent(of: .value) { (snapshot) in
if snapshot.hasChild(self.post.postKey){
self.setVotesLbl()
self.showVoteViews()
self.disableBtns()
} else {
self.hideVoteViews()
self.enableBtns()
}
}
}
in :
override func prepareForReuse() {
super.prepareForReuse()
hideVoteViews()
getCellData()
}
and also in:
override func awakeFromNib() {
super.awakeFromNib()
hideVoteViews()
getCellData()
}
I hope this will resolve the issue :)
Upvotes: 1
Reputation: 25
You should not set an observer while awaking a cell from nib. Because while reusing the cell awakefromnib of PostCell will not get called and hence the data of old cell will be reflected to your reused cell. The better way is to set a observer to your "likes" root node and store the value in you data structure. After that you can reload the table using this data structure.
Upvotes: 1
Reputation: 4918
First you need to customize your cells in cellForRowAtIndexPath not in awakeFromNib.
Second, You need to reset your label and views before the cell is reused by overriding prepareForReuse.
override func prepareForReuse() {
super.prepareForReuse()
hideVoteViews()
self.altAVotesLbl.text = ""
}
Upvotes: 0
Reputation: 58049
You should set the text of all labels, or the previous text will be reused.
You should also use NumberFormatter
for converting numeric values to numbers instead of creating string literals from them.
let formatter = NumberFormatter()
if let aVotes = post?.altAVotes {
altAVotesLbl.text = formatter.string(from: aVotes as NSNumber)
} else {
altAVotesLbl.text = ""
}
[...]
Upvotes: 0