Akshay Kheveria
Akshay Kheveria

Reputation: 211

Adding UIButton (follow button) in UITableView using swift

So here is my Problem.. I've retrieved the user data from _User class in Parse and showing it in the app as follows:

var data:NSMutableArray = NSMutableArray()


func loadData() {

    data.removeAllObjects()

    var userQuery = PFUser.query()
        userQuery?.orderByAscending("createdAt")
        userQuery?.findObjectsInBackgroundWithBlock({ (objects, erroe) -> Void in

            if let objects = objects {

                for object in objects {

                    if let user = object as? PFUser {

                        if user.objectId != PFUser.currentUser()?.objectId {

                            self.data.addObject(object)



                        }

                        self.tableView.reloadData()


                    }

                }
            } 
        })
}

override func viewDidLoad() {
    super.viewDidLoad()

    loadData()

}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()

}

// MARK: - Table view data source

override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    // #warning Potentially incomplete method implementation.
    // Return the number of sections.
    return 1
}

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    // #warning Incomplete method implementation.
    // Return the number of rows in the section.
    return data.count

}


override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let myCell = tableView.dequeueReusableCellWithIdentifier("users", forIndexPath: indexPath) as! userListTableViewCell

    let userData:PFObject = self.data.objectAtIndex(indexPath.row) as! PFObject

    // Usernames and gender..

    myCell.fullName.text = userData.objectForKey("fullName") as! String!
    myCell.genderLabel.text = userData.objectForKey("gender") as! String!

    // Profile pictures..

    let profilePics = userData.objectForKey("profilePicture") as! PFFile
    profilePics.getDataInBackgroundWithBlock { (data, error) -> Void in

        if let downloadedImage = UIImage(data: data!) {

            myCell.dp.image = downloadedImage
        }

    }
    return myCell
}

Now I want to add a follow button to follow a particular user and want to save that data in Parse. So my questions are:

  1. How can I add the follow button effectively which would not mess up things if there are so many users.. I've tried giving them tag like myCell.followButton.tag = indexPath.row but it dint work well. so I want to know about some other way for achieving my goal.

  2. What is the best possible way to save the follower list in Parse.. I'm thinking to make a class named Followers having the columns user : the user being followed and follower where we can add the PFUser.currentUser().objectId . Is there anything better than this or this is a nice method to do it?

here is the screen shot of my userListTableViewController..

enter image description here

Here you can see the followButton which i've already connected to userListTableViewCell.. Please help me out.. Thanks for your time..

Upvotes: 0

Views: 1024

Answers (1)

dGambit
dGambit

Reputation: 531

Lets make that button you want a UILabel instead and add a UIGestureRecognizer to it, one like this

Create a swift file named PFUserTapGestureRecognizer.swift

import UIKit

class PFUserTapGestureRecognizer: UITapGestureRecognizer
{
    var tapper: PFUserTapper

    init(id: Int, onTap: (id: Int) -> Void)
    {
        self.tapper = PFUserTapper()
        self.tapper.id = id
        self.tapper.onTap = onTap
        super.init(target: self.tapper, action: Selector("userTapped"))
    }
}

class PFUserTapper : NSObject
{
    var id = 0
    var onTap: ((idUse: Int) -> Void)?

    func userTapped()
    {
        onTap?(idUser: id)
    }
}

Now, when you load your cell in your view controller where you are loading your UITableView, in the delegate tableView:cellForRowAtIndexPath:, do this:

// Check if you are following that user already
// if im NOT following this user then
{
    let idUser = userData.objectForKey("id") as! Int
    myCell.labelFollow.tag = idUser
    myCell.labelFollow.text = "Follow"
    addFollowBehavior(follow: true, idUser: idUser, label: myCell.labelFollow)
}
// else if i'm following the user
{
    myCell.labelFollow.text = "Unfollow"
    addFollowBehavior(follow: false, idUser: idUser, label: myCell.labelFollow)
}
// else.. you should consider the case when you click Follow and it takes time to get an answer from your service

And create this function

func addFollowBehavior(follow follow: Bool, idUser: Int, label: UILabel) 
{
    if let recognizers = label.gestureRecognizers {
        for recognizer in recognizers {
            label.removeGestureRecognizer(recognizer as! UIGestureRecognizer)
        }
    }
    label.addGestureRecognizer(PFUserTapGestureRecognizer(idUser, 
        onTap: { (idUser) -> Void in
            // THIS IS WHERE YOU SAVE TO PARSE, WEB SERVICE OR WHATEVER
            // if follow then 
                // Do Follow 
            // else 
                // UnFollow... 

            // On the callback write this to protect from reused cells:
            if label.tag = idUser {
                myCell.labelFollow.text = follow ? "Unfollow" : "Follow" // NOW (UN)FOLLOWING!
                addFollowBehavior(follow: !follow, idUser: idUser, label: myCell.labelFollow)
            }
        }
    )
}

I didn't had the chance to test it but I have a very similar implementation on a requirement like that and it works perfectly

Note: this works if the follow item is an UIImageView or whatever inherits from UIView for a cooler look, instead of changing the text, you change the UIImage

Upvotes: 1

Related Questions