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!
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

jean-marie castellucci
4,954 PointsRibbit/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
42,016 Pointsnot 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
4,954 PointsThis 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
42,016 Pointscan you post the full code for your table view controller?

jean-marie castellucci
4,954 PointsIt's working !! I took the second option.
Wish one day i'll be a dev master yoda like you. Thanks.

Stone Preston
42,016 Pointsno problem, glad I could help

Jake Giganti
1,981 Pointsjean-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
}