2

I am trying to implement a like/unlike feature in my iOS app using Swift 2.0, Storyboard, and Parse where users can like/unlike posts created by other users or themselves - just like Instagram, Facebook, and other social apps.

I have a button wired up in the Storyboard to an IBOutlet called likeButton and an IBAction called likeButtonTapped.

I am confident that the cellForRowAtIndexPath method is also involved in implementing this functionality correctly.

I think that I have the right idea of what needs to happen in the comments of my code below, however, I do not know how to check if a specific post is liked or not. How do I check if the post is liked or not so that I can toggle the likeButton image, increment/decrement the likeCount, and add/remove the relation between the current user and the post that the user likes.

Also, am I taking the "right" (conventional) approach for a standard like/unlike feature? I would love to hear your feedback. Thank you for your time and help!

class TimelineFeedViewController: PFQueryTableViewController {
    var userLike = PFUser.currentUser()?.relationForKey("likes")

    @IBAction func likeButtonTapped(sender: UIButton) {
        // The following code has errors - for example, `object` is an unresolved 
        // identifier (it's supposed to be a PFObject that holds a post at a specific 
        // indexPath)
        // Also, I cant access the likeButton for some reason. Only when I do
        // cell.likeButton in `cellForRowAtIndexPath`.
        // If the button is liked already (it's filled)
        // Toggle likeButton image to UNfilled version
        // "if likeButton isLiked == true" below is pseudocode of what I am trying to do
        if likeButton isLiked == true {
            let image = UIImage(named: "likeButtonUnfilled")
            cell.likeButton.setImage (image, forState: UIControlState)

            // Decrement the likeCount
            object!.decrementKey("count")

            // Remove the relation bet user and post
            self.userLike?.removeObject(object!)
        } else {
            // the button is NOT liked already (it's not filled)
            // toggle the image to the filled version
            let image = UIImage(named: "likeButton")
            cell.likeButton.setImage (image, forState: UIControlState)

            // Increment the likeCount
            object!.incrementKey("count")

            // Add the relation bet. user and post
            self.userLike?.addObject(object!)
        }

        object!.saveIngBackground()
        PFUser.currentUser()?.saveInBackground()

        self.tableView.reloadData()
    }
}
dnadri
  • 173
  • 1
  • 2
  • 11
  • You have button in UITableViewCell?? – Saqib Omer Dec 04 '15 at 09:03
  • @SaqibOmer I implemented IBOutlets like the likeButton, etc in a separate swift class file which subclasses UITableViewCell – dnadri Dec 04 '15 at 09:05
  • Increment and decrement is usually better done in cloud code. Storing the likes in a relation will work ok. – Wain Dec 04 '15 at 09:41
  • @Wain My increment and decrement lines of code (i.e.: `.incrementKey("count")`) are updating the count column (like count) in Parse cloud though... – dnadri Dec 04 '15 at 17:24
  • @Wain Also, when I try to print out the relation `userLike`, I get something like: " userLike: Optional( PostClass>) " ... In Parse, when I click on a relation in the replies column of the User class, it shows me all the posts liked by that user. Now I'm not sure how I can access this list in code (ie: so that I can use it in my if/else control block when checking which posts are liked or not). – dnadri Dec 04 '15 at 17:25

1 Answers1

-1

Assuming you have custom UITableViewCell class and have fetched data from Parse, than in you UITableView data source method

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCellWithIdentifier("skillsCell", forIndexPath: indexPath) as! YOURTableViewCell
    //Check If item is liked
    if (isLiked) {

      //Set image for like on button
      }
      else {
          //Set image for unlike on button
      }
    cell.YourButton.tag = indexPath.row // This will assign tag to each button in tableView

    return cell
}

Than in YourViewController add UIButton Action

@IBAction func testButtonAction(sender: UIButton) {

    print(sender.tag)

    let cell = testTableView.cellForRowAtIndexPath(NSIndexPath(forRow: sender.tag, inSection: 0)) as! TestTableViewCell

    if cell.likeButton.titleLabel?.text == "Cell \(sender.tag)" { //Your logic here. Check If button's image has "Liked Image than change Image to UnLiked Image"
        cell.likeButton.text = "\(sender.tag)"
    }
    else {
        cell.likeButton.text = "Cell \(sender.tag)"
    } 
}

This will implement Like/Unlike for button in UITableView. Also make sure you update your Class in Parse accordingly.

Saqib Omer
  • 5,387
  • 7
  • 50
  • 71
  • Thanks Saqib. I created a Like class in Parse. See updated question. Few questions though: 1.) Where is the bool isLiked in `if (isLiked)`? I can't access Parse this way. 2.) I'm not sure when you say "Than in YourViewController add UIButton Action" if you mean in ANOTHER file. My IBAction likeButtonTapped and `cellForRowAtIndexPath` methods are implemented in the same file/class: `class TimelineFeedViewController: PFQueryTableViewController`. 3) `cell.likeButton.text = "\(sender.tag)"` is giving me this error in the if and else statements: "Value of type 'UIButton' has no member 'text'. – dnadri Dec 04 '15 at 18:02
  • 3,) (continued) I am not trying to change the _text_ of the likeButton, just the _image_ of the likeButton. I appreciate you clarifying your answers to these 3 questions! – dnadri Dec 04 '15 at 18:06