问题
I added button into cell-s and added action so if user touches it then the state is "Dislike" and if user touches again the state is "Like". However, the state applies to other cell buttons also. And if I scroll fast it just randomly picks what cell button should have the state. What causes this?
I call button with function inside cellForRowAt indexPath: IndexPath
function like this:
cell.likeButton.addTarget(self, action: #selector(like), for: .touchUpInside)
And this is the function that is assigned to the button:
func like(sender: UIButton){
let section = 0
let row = sender.tag
let indexPath = IndexPath(row: row, section: section)
let cell: FeedTableViewCell = tableView.dequeueReusableCell(withIdentifier: "feedCell", for: indexPath) as! FeedTableViewCell
FIRDatabase.database().reference().child("posts").child(postsArray[indexPath.row].key).runTransactionBlock({ (currentData: FIRMutableData) -> FIRTransactionResult in
if var post = currentData.value as? [String : AnyObject], let uid = FIRAuth.auth()?.currentUser?.uid {
var stars : Dictionary<String, Bool>
stars = post["stars"] as? [String : Bool] ?? [:]
var starCount = post["starCount"] as? Int ?? 0
if let _ = stars[uid] {
// Unstar the post and remove self from stars
starCount -= 1
stars.removeValue(forKey: uid)
cell.likeButton.tag = indexPath.row
cell.likeButton.setTitle("Like", for: .normal)
cell.likeLabel.text = "\(starCount)"
} else {
// Star the post and add self to stars
starCount += 1
stars[uid] = true
cell.likeButton.tag = indexPath.row
cell.likeButton.setTitle("Dislike", for: .normal)
cell.likeLabel.text = "\(starCount)"
}
post["starCount"] = starCount as AnyObject?
post["stars"] = stars as AnyObject?
// Set value and report transaction success
currentData.value = post
return FIRTransactionResult.success(withValue: currentData)
}
return FIRTransactionResult.success(withValue: currentData)
}) { (error, committed, snapshot) in
if let error = error {
print(error.localizedDescription)
}
}
}
And like this I created the tableview with cells:
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell: FeedTableViewCell = tableView.dequeueReusableCell(withIdentifier: "feedCell", for: indexPath) as! FeedTableViewCell
cell.likeButton.tag = indexPath.row
cell.likeButton.addTarget(self, action: #selector(self.tapped), for: .touchUpInside)
}
What causes the state to transfer to the other buttons also? I even added tags so it detects the selected button. Is there something to do with cell reuse?
It adds likes to Firebase to the right one..
回答1:
I think this issue is because of dequeuing your cell twice. you should try;
func like(sender: UIButton){
//your code ...
let cell: FeedTableViewCell = self.tableViewAddress.cellForRowAtIndexPath(indexPath) as! FeedTableViewCell
//Your code ...
回答2:
var selectindex : Int?
var selectedindex : NSMutableArray = NSMutableArray()
@IBOutlet var tableview: UITableView!
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("LikeCell", forIndexPath: indexPath)
let like: UIButton = (cell.viewWithTag(2) as! UIButton)
let comment: UIButton = (cell.viewWithTag(3) as! UIButton)
if selectedindex.containsObject(indexPath.row) {
like.setBackgroundImage(UIImage.init(named: "like.png"), forState: .Normal)
}else{
like.setBackgroundImage(UIImage.init(named: "like (1).png"), forState: .Normal)
}
comment.setBackgroundImage(UIImage(named: "chat.png"), forState: UIControlState.Normal)
like.addTarget(self, action: #selector(self.CloseMethod(_:event:)), forControlEvents: .TouchDown)
comment.addTarget(self, action: #selector(self.CloseMethod1(_:event:)), forControlEvents: .TouchDown)
return cell
}
@IBAction func CloseMethod(sender: UIButton, event: AnyObject) {
let touches = event.allTouches()!
let touch = touches.first!
let currentTouchPosition = touch.locationInView(self.tableview)
let indexPath = self.tableview.indexPathForRowAtPoint(currentTouchPosition)!
selectindex = indexPath.row
if selectedindex.containsObject(selectindex!) {
selectedindex.removeObject(selectindex!)
// call your firebase method for update database
}else{
selectedindex.addObject(selectindex!)
// call your firebase method for update database
}
self.tableview.reloadData()
}
Output :
https://www.dropbox.com/s/ub7wln5y6hdw0sz/like%20button.mov?dl=0
回答3:
This is caused by reusing previous cells when scrolling and is the base mechanism of a table view.
You need to reset the state of your button on every call to cellForRowAtIndexPath
.
Between let cell = ...
and cell.starButton.addTarget
you need to perform something like cell.starButton.deselect()
, or .select()
, based on the index path you're working on.
来源:https://stackoverflow.com/questions/40025473/button-state-activates-on-wrong-cells