Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

iOS

jean-marie castellucci
jean-marie castellucci
4,954 Points

Ribbit/swift : Add a button in tableViewCell to follow a user in parse

Hi i want to add a follow button in tableViewCell. I can't get this working since i don't know how to pass data from the cell to the IBAction methods.

This is my code what should i do ?

 @IBAction func followButton(sender: AnyObject) {


    if tableView != nil {

        if var indexPath :NSIndexPath = self.tableView.indexPathForSelectedRow() {



            let user:PFObject = self.userList.objectAtIndex(indexPath.row) as PFObject
            var relation : PFRelation = PFUser.currentUser().relationForKey("KfriendsRelation")
            relation.addObject(user)
            PFUser.currentUser().saveInBackgroundWithBlock { (succeed:Bool, error: NSError!) -> Void in
                if error != nil {

                }

            }


        }


       println("not working")

    }

5 Answers

Stone Preston
Stone Preston
42,016 Points

not sure if the standard IBAction is going to work (it might though). you may have to call set target for action on your button in cellForRow.

add your button as an outlet to your custom cell class. then in cellForRow set the index.row of the cell as the buttons tag. this will allow you to reference the data of the tableView at the specified cell from within the button method. then in the IBAction you just get the data at the index path by using the tag of the button

override  func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell: AddFirendsTableViewCell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath)as AddFirendsTableViewCell

   //set the buttons tag to the index path.row
   cell.button.tag = indexPath.row;

    ...

then in the action

IBAction func followButton(sender: AnyObject) {

   button: UIButton = sender as UIButton;
   //use the tag to index the array
   let user:PFObject = self.userList.objectAtIndex(button.tag) as PFObject
            var relation : PFRelation = PFUser.currentUser().relationForKey("KfriendsRelation")
            relation.addObject(user)
            PFUser.currentUser().saveInBackgroundWithBlock { (succeed:Bool, error: NSError!) -> Void in
                if error != nil {

                }

            }

}

if that action does not fire you may just have to make it a regular method, and set it as the buttons target in cellForRow

override  func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell: AddFirendsTableViewCell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath)as AddFirendsTableViewCell

   //set the buttons tag to the index path.row
   cell.button.tag = indexPath.row;
   cell.button.addTarget(self, action: "followButton:", forControlEvents: .TouchUpInside)

    ...

then define the action method:

 func followButton(sender: AnyObject) {

   button: UIButton = sender as UIButton;
   //use the tag to index the array
   let user:PFObject = self.userList.objectAtIndex(button.tag) as PFObject
            var relation : PFRelation = PFUser.currentUser().relationForKey("KfriendsRelation")
            relation.addObject(user)
            PFUser.currentUser().saveInBackgroundWithBlock { (succeed:Bool, error: NSError!) -> Void in
                if error != nil {

                }

            }

}
jean-marie castellucci
jean-marie castellucci
4,954 Points

This is all my code :

import UIKit

class AddFriendsTableViewController: UITableViewController, UISearchBarDelegate {

override func preferredStatusBarStyle() -> UIStatusBarStyle {
    return UIStatusBarStyle.LightContent
  }

@IBOutlet var searchBar: UISearchBar!

func searchBarSearchButtonClicked(searchBar: UISearchBar) {


    searchBar.text.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceAndNewlineCharacterSet())
    loadUser()
}

var userList:NSMutableArray = NSMutableArray()


func searchBarShouldBeginEditing(searchBar: UISearchBar!) -> Bool {
    return true
}

func searchBarShouldEndEditing(searchBar: UISearchBar!) -> Bool {
    return true

}

func searchBar(searchBar: UISearchBar!, textDidChange searchText: String!) {

}

func loadUser () {

    userList.removeAllObjects()
    var findUser:PFQuery = PFUser.query()
    findUser.whereKey("username", containsString: searchBar.text.lowercaseString)

    findUser.whereKey("username", notEqualTo: PFUser.currentUser().username)



    findUser.findObjectsInBackgroundWithBlock { (objects:[AnyObject]!, error:NSError!) -> Void in
        if !(error != nil) {
            // The find succeeded.
            println("succesfull load Users")
            // Do something with the found objects
            for object  in objects  {
                self.userList.addObject(object)
                println("users added to userlist")
            }
            self.tableView.reloadData()
        } else {
            // Log details of the failure
            println("error loadind user ")
            println("error")
        }

    }
}





override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    return 1
}

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return userList.count
}



override  func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell: AddFirendsTableViewCell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath)as AddFirendsTableViewCell

    let users:PFObject = self.userList.objectAtIndex(indexPath.row) as PFObject





    var findUserName:PFQuery = PFUser.query()

    findUserName.findObjectsInBackgroundWithBlock{
        (objects:[AnyObject]!, error:NSError!) -> Void in

        if !(error != nil) {

            if let user:PFUser = users as? PFUser {
                cell.userNameTextField.text = user.username
                println("user exist")
                // define avatar poster

                if let avatarImage:PFFile = user["profileImage"] as? PFFile {
                    avatarImage.getDataInBackgroundWithBlock{(imageData:NSData!, error:NSError!)-> Void in

                        if !(error != nil) {

                            let image:UIImage = UIImage(data: imageData)


                            cell.avatarImage.image = image as UIImage
                            cell.avatarImage.layer.cornerRadius = cell.avatarImage.frame.size.width / 2
                            cell.avatarImage.clipsToBounds = true

                        }

                    }

                }
                else {
                    cell.avatarImage.image = UIImage(named: "Avatar-1")
                    cell.avatarImage.layer.cornerRadius = cell.avatarImage.frame.size.width / 2
                    cell.avatarImage.clipsToBounds = true
                }
            }

        }


    }

    return cell
}




@IBAction func followButton(sender: AnyObject) {


    if tableView != nil {

        if var indexPath :NSIndexPath = self.tableView.indexPathForSelectedRow() {



            let user:PFObject = self.userList.objectAtIndex(indexPath.row) as PFObject
            var relation : PFRelation = PFUser.currentUser().relationForKey("KfriendsRelation")
            relation.addObject(user)
            PFUser.currentUser().saveInBackgroundWithBlock { (succeed:Bool, error: NSError!) -> Void in
                if error != nil {

                }

            }


        }


       println("not working")

    }




}



override func viewWillAppear(animated: Bool) {
    super.viewWillAppear(true)

    self.tableView.separatorColor = UIColor.whiteColor()
    navigationController?.navigationBar.hidden =  false


}



override func viewDidAppear(animated: Bool) {




}

override func viewDidLoad() {

    self.searchBar.delegate = self
}

}

Stone Preston
Stone Preston
42,016 Points

can you post the full code for your table view controller?

jean-marie castellucci
jean-marie castellucci
4,954 Points

It's working !! I took the second option.

Wish one day i'll be a dev master yoda like you. Thanks.

Stone Preston
Stone Preston
42,016 Points

no problem, glad I could help

Jake Giganti
Jake Giganti
1,981 Points

jean-marie castellucci and Stone Preston: I'm having some difficulty getting this to work properly. Specifically, I'm unsure with how to define the action. Here is my cellForRowAtIndexPath code. Any help here would be appreciated. Thanks.

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        //ask for a reusable cell from the tableview, the tableview will create a new one if it doesn't have any
        let cell: UserSearchTableViewCell = tableView.dequeueReusableCellWithIdentifier("usersCell") as UserSearchTableViewCell

        //set the buttons tag to the index path.row
        cell.addFriendButton.tag = indexPath.row;
        cell.addFriendButton.addTarget(self, action: "followButton:", forControlEvents: .TouchUpInside)

        let users:PFObject = self.userList.objectAtIndex(indexPath.row) as PFObject


        var findUserName:PFQuery = PFUser.query()
        findUserName.whereKey("username", containsString: searchText.text)

        findUserName.findObjectsInBackgroundWithBlock{
            (objects:[AnyObject]!, error:NSError!) -> Void in

            if !(error != nil) {

                if let user:PFUser = users as? PFUser {
                    cell.searchResultsLabel.text = user.username
                    println("user exist")
                }
            }
        }
        func followButton(sender: AnyObject) {

            button: UIButton = sender as UIButton //THIS LINE IS THROWING THE ERROR
            //use the tag to index the array
            let user:PFObject = self.userList.objectAtIndex(cell.addFriendButton.tag) as PFObject
            var relation : PFRelation = PFUser.currentUser().relationForKey("Friends")
            relation.addObject(user)
            PFUser.currentUser().saveInBackgroundWithBlock { (succeed:Bool, error: NSError!) -> Void in
                if error != nil {

                }

            }

        }
        return cell
    }