UIButton图像在可重复使用的tableview单元格中切换问题

时间:2016-02-24 18:41:32

标签: ios swift

我正在尝试在我的社交网络iOS应用中实现类似的功能 - 使用Swift,Parse作为后端,以及Storyboard - 用户可以喜欢(而且不像)与Instagram或Facebook iOS应用类似的帖子。

唯一的问题似乎是,当用户滚动帖子的tableview供稿时,当前用户不喜欢的其他帖子会显示填充的按钮图像(就像他们被喜欢,但他们不是) 。

根据我的研究,我了解到这可能会发生,因为tableview中的单元格是可重用的(通过tableView.dequeueReusableCellWithIdentifier。)*这是有道理的,因为当用户打开应用程序时,只有可见的单元格已加载。当用户滚动tableview时,单元格将被回收。

因此,我进行了一些研究,发现尝试解决此问题的一个选项是使用prepareForReuse()方法重置likeButton IBOutlet的自定义单元格图像。 tableView中的表视图委托:cellForRowAtIndexPath:然后在重用单元格时重置所有内容,包括具有基于从类似查询获得的结果的某些逻辑的likeButton图像。它起初很有用,但遗憾的是,当用户试图喜欢帖子时,由于某种原因这会破坏like按钮的行为。

更新:此处不需要prepareForResuse()作为答案之一。

// In custom cell file:

    override func prepareForReuse() {
        super.prepareForReuse()

        // Set likeButton image to the default unfilled version
        let image = UIImage(named: "likeButtonUnfilled")
        self.likeButton.setImage(image, forState: UIControlState.Normal)

    }

在帖子Feed视图控制器文件的cellForRowAtIndexPath中:

        // currUserLikeObjects is an array of PFObjects that contains the results returned from the like query (all of the objects that the current user has liked) 
        for object in currUserLikeObjects {

            if object["toPost"]?.objectId! == postObject.objectId {

                // Toggle likeButton image to filled version
                let image = UIImage(named: "likeButtonFilled") as UIImage!
                cell.likeButton.setImage(image, forState: UIControlState.Normal)

            }

        }

在帖子Feed视图控制器文件的likeButtonTapped中:

func likeButtonTapped(sender: UIButton) {

    sender.enabled = false

    let indexPath = NSIndexPath(forRow: sender.tag, inSection: 0)
    let cell = tableView.cellForRowAtIndexPath(indexPath) as! PostTableViewCell

    let likeObject = PFObject(className: ParseHelper.ParseLikeClass)
    var likedPost: PFObject = (self.objects![indexPath.row] as? PFObject)!

        if (cell.likeButton.currentImage!.isEqual(UIImage(named: "likeButtonUnfilled"))) {
            /* The post is NOT liked already by the currentUser (likeButton image is NOT filled)
            1. Save the like object to Parse
            2. If successfully saved, increment the likeCount and update it in Parse (Remember: Enable likeButton)
            3. If successfully saved, toggle the image to the filled version
            */

            // 1
            likeObject["fromUser"] = PFUser.currentUser()!
            likeObject["toPost"] = likedPost

            likeObject.saveInBackgroundWithBlock { (success: Bool, error: NSError?) -> Void in

                if (error == nil) {
                    print("SUCCESS: Saved likeObject in database.")

                    // 2
                    likedPost.incrementKey(ParseHelper.ParsePostLikeCount, byAmount: 1)
                    likedPost.saveInBackgroundWithBlock { (success: Bool, error: NSError?) -> Void in

                        if (error == nil) {
                            // The likeCount key has been incremented
                            print("SUCCESS: The likeCount key has been incremented. Toggling like button image to FILLED.")

                            // 3
                            var image = UIImage(named: Helper.likeButtonFilled)
                            cell.likeButton.setImage(image, forState: UIControlState.Normal)

                        } else {
                            // There was a problem, check error.description
                            print("FAIL: The likeCount key has NOT been incremented.")

                            // Delete the likeObject since the likeCount was not successfully saved
                            likeObject.deleteInBackgroundWithBlock( {(succeeded: Bool?, error: NSError?) -> Void in

                                if (error == nil) {
                                    print("SUCCESS: Deleted likeObject from Parse since likeCount key has not successfully been incremented.")

                                    self.showAlertMessage((error?.description)!)

                                } else {
                                    print("FAIL: Unable to delete the likeObject from Parse in response to likeCount key NOT incrementing.")

                                }

                            })

                        }

                    }

                    print("Enabling sender & reloading data.")
                    sender.enabled = true
                    self.tableView.reloadData()

                } else {
                    print("FAIL: Unable to save like object in Parse.")
                    self.showAlertMessage("Unable to like this post at this time.")

                }
            }

        } else if (cell.likeButton.currentImage!.isEqual(UIImage(named: "likeButtonFilled"))) {
            /* The post is liked already by the currentUser (likeButton image is filled)
            1. Delete the likeObject from Parse
            2. If successfully deleted, only if the likeCount is greater than 0 to avoid a negative likeCount, decrement the likeCount and update it in Parse (Remember: Enable likeButton)
            3. If successfully deleted, toggle the image to the unfilled version
            */

            // 1
            likeObject.deleteInBackgroundWithBlock( {(succeeded: Bool?, error: NSError?) -> Void in

                if (error == nil) {
                    print("SUCCESS: Deleted likeObject from Parse (unliked post).")

                    // 2
                    likedPost.incrementKey(ParseHelper.ParsePostLikeCount, byAmount: -1)

                    likedPost.saveInBackgroundWithBlock { (success: Bool, error: NSError?) -> Void in

                        if (error == nil) {
                            // The likeCount key has been decremented
                            print("SUCCESS: The likeCount key has been decremented.")

                            // 3
                            var image = UIImage(named: Helper.likeButtonUnfilled)
                            cell.likeButton.setImage(image, forState: UIControlState.Normal)

                        } else {
                            print("FAIL: The likeCount key has NOT been decremented.")

                            // Delete the likeObject from the Like class since the likeCount was not successfully saved?

                        }

                    }

                    print("Enabling sender & reloading data.")
                    sender.enabled = true
                    self.tableView.reloadData()

                } else {

                    print("FAIL: Unable to delete the like object from Parse.")

                }

            })

        } 

} 

1 个答案:

答案 0 :(得分:0)

在您的案例中无需使用prepareForReuse方法,您可以通过以下方式替换cellForRowAtIndexPath中的代码来实现:

// Set likeButton image to the default unfilled version
var image = UIImage(named: "likeButtonUnfilled")

// currUserLikeObjects is an array of PFObjects that contains the results returned from the like query (all of the objects that the current user has liked) 
for object in currUserLikeObjects {
    if object["toPost"]?.objectId! == postObject.objectId {
         // Toggle likeButton image to filled version
         image = UIImage(named: "likeButtonFilled") as UIImage!
         break // Terminate loop when we found required object
    }
}
self.likeButton.setImage(image, forState: UIControlState.Normal)

为了使上述代码正常工作,还要求您在完成Like / Different操作时相应地更新currUserLikeObjects并更新特定的tableview单元以反映屏幕上的修改。