按钮状态在错误的单元格上激活

Posted

技术标签:

【中文标题】按钮状态在错误的单元格上激活【英文标题】:Button state activates on wrong cells 【发布时间】:2016-10-13 15:43:15 【问题描述】:

我将按钮添加到单元格中并添加了操作,因此如果用户触摸它,则状态为“不喜欢”,如果用户再次触摸,则状态为“喜欢”。但是,该状态也适用于其他单元格按钮。如果我快速滚动它只是随机选择哪个单元格按钮应该具有状态。这是什么原因造成的?

我在cellForRowAt indexPath: IndexPath函数中调用按钮,函数如下:

cell.likeButton.addTarget(self, action: #selector(like), for: .touchUpInside)

这是分配给按钮的功能:

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)
        
    

像这样我用单元格创建了表格视图:

     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)
    

是什么导致状态也转移到其他按钮?我什至添加了标签,以便它检测到选定的按钮。与细胞重复使用有关吗?

它将对 Firebase 的喜欢添加到正确的..

【问题讨论】:

回答你的最后一个问题,用两个词:细胞重用。您需要向我们展示您是如何创建和返回单元格的。 @Cyrille 我编辑了。 如果您的喜欢按钮是您的单元格的直接子级,您应该尝试通过询问表格视图而不是基于标签创建新的来获取indexPathlet cellIndexPath = tableView.indexPathForCell(sender.superview) 好点,我今晚要试试。 @Crazyrems 仍然无法正常工作:( 【参考方案1】:

这是由于在滚动时重复使用以前的单元格造成的,并且是表格视图的基本机制。

您需要在每次调用 cellForRowAtIndexPath 时重置按钮的状态。

let cell = ...cell.starButton.addTarget 之间,您需要根据您正在处理的索引路径执行cell.starButton.deselect().select() 之类的操作。

【讨论】:

我在调用该函数之前尝试了cell.starbutton.deselect,是的,它现在不选择其他人,但如果它不在视线范围内,它会取消选择它。但是“基于您正在处理的索引路径”是什么意思?【参考方案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()
    

输出

https://www.dropbox.com/s/ub7wln5y6hdw0sz/like%20button.mov?dl=0

【讨论】:

您在 CloseMethod 函数上附加了什么按钮? @TarvoMäesepp 喜欢按钮。查看我的视频【参考方案3】:

我认为这个问题是因为你的单元格出队两次。你应该试试;

func like(sender: UIButton)
    //your code ...
    let cell: FeedTableViewCell = self.tableViewAddress.cellForRowAtIndexPath(indexPath) as! FeedTableViewCell
    //Your code ...

【讨论】:

成功了 :O 但是现在如果我快速点击 2 次它会增加 +2

以上是关于按钮状态在错误的单元格上激活的主要内容,如果未能解决你的问题,请参考以下文章

在 iPhone 中的单元格上获取选中和未选中按钮问题

将组合框单元格上的双击激活更改为单击?

按钮图像在单元格上重复

在表格视图中按下单元格上的按钮时如何创建新单元格

单元格中的选定按钮显示在重用单元格上 - 也使用 sender.tag 进行按钮区分

当点击单元格上的按钮时,将信息写入单元格中