Atakan Cavuslu Atakan Cavuslu - 2 months ago 21
Swift Question

How to give different tags to buttons in different TableView cells in Swift

I'm developing an app where users writes entries to different topics then can give up and down points to the entries. I used in my tableViewController the function:


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


and I added these two lines at the end of this function:

cell.plusButton.tag = indexPath.row
cell.minusButton.tag = indexPath.row


So this should give every button in the tableView a tag so that its the same as indexpath.row of that cell, am I wrong? Because when I then try to call the buttons, all of their tags are same and equals to 0. How can I give them different tags? Is there no way to do so in this way?

This is what the code is when I want to call the button:

@IBAction func plus(sender: AnyObject) {

print(self.tag)

let ref = FIRDatabase.database().reference().child("topics/"+topicClicked+"/"+entriesArrayTwo[self.tag])

var value = Int()
var date = String()
var user = String()
var votedDown = [""]
var votedUp = [""]

ref.observeSingleEventOfType(.Value, withBlock: { snapshot in
let dict = snapshot.value as! [String: AnyObject]

value = dict["point"] as! Int
date = String(dict["date"]!)
user = String(dict["user"]!)
votedUp = dict["votedUp"] as! NSArray as! [String]
votedDown = dict["votedDown"] as! NSArray as! [String]

var tempBool = false
var temp = -1

for uid in votedDown {
temp = temp + 1

if uid == FIRAuth.auth()?.currentUser?.uid {
votedDown.removeAtIndex(temp)
tempBool = true
}
}

if tempBool == false {
votedUp.append((FIRAuth.auth()?.currentUser?.uid)!)
}

ref.setValue(["point": value+1, "date": date, "user": user, "votedDown": votedDown, "votedUp": votedUp])

self.point.text = String(value+1)
})

if minusButton.hidden == true {
minusButton.hidden = false
} else {
plusButton.hidden = true
}
}


My tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell function is below:

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "entryCell", for: indexPath) as! HubEntryTableViewCell

if self.resultSearchController.isActive {

let ref = FIRDatabase.database().reference().child("topics/"+topicClicked+"/"+filteredTableData[(indexPath as NSIndexPath).row])

ref.observeSingleEvent(of: .value, with: { snapshot in

let value = snapshot.value as? NSDictionary

cell.point.text = String(describing: value!["point"]!)

let postRef = FIRDatabase.database().reference().child("users/"+String(describing: value!["user"]!))

postRef.observeSingleEvent(of: .value, with: { snapshotTwo in

let valueTwo = snapshotTwo.value as? NSDictionary

cell.subInfo.text = String(describing: valueTwo!["name"]!)+" "+String(describing: valueTwo!["surname"]!)+" - "+String(describing: value!["date"]!)

})


})

cell.entry.text = self.filteredTableData[(indexPath as NSIndexPath).row]

} else {

let ref = FIRDatabase.database().reference().child("topics/"+topicClicked+"/"+entriesArray[(indexPath as NSIndexPath).row])

ref.observeSingleEvent(of: .value, with: { snapshot in

let value = snapshot.value as? NSDictionary

cell.point.text = String(describing: value!["point"]!)

let postRef = FIRDatabase.database().reference().child("users/"+String(describing: value!["user"]!))

postRef.observeSingleEvent(of: .value, with: { snapshotTwo in

let valueTwo = snapshotTwo.value as? NSDictionary

cell.subInfo.text = String(describing: valueTwo!["name"]!)+" "+String(describing: valueTwo!["surname"]!)+" - "+String(describing: value!["date"]!)

})

let votedUpRef = ref.child("votedUp")

votedUpRef.observeSingleEvent(of: .value, with: { upSnapshot in

var tempDict = snapshot.value as! [String: AnyObject]
let tempArray = tempDict["votedUp"] as! [String]

for uid in tempArray {

if String(uid) == FIRAuth.auth()?.currentUser?.uid {

cell.plusButton.isHidden = true

}

}

})

let votedDownRef = ref.child("votedDown")

votedUpRef.observeSingleEvent(of: .value, with: { upSnapshot in

var tempDict = snapshot.value as! [String: AnyObject]
let tempArray = tempDict["votedDown"] as! [String]

for uid in tempArray {

if String(uid) == FIRAuth.auth()?.currentUser?.uid {

cell.minusButton.isHidden = true

}

}

})

})

cell.entry.text = self.entriesArray[(indexPath as NSIndexPath).row]

}

cell.plusButton.tag = (indexPath as NSIndexPath).row
cell.minusButton.tag = (indexPath as NSIndexPath).row

// NEW METHOD TO GET THE BUTTON

let check1: UIButton = (cell.viewWithTag(1) as! UIButton)
let check2: UIButton = (cell.viewWithTag(2) as! UIButton)
check1.addTarget(self, action: #selector(HubEntriesTableViewController.CloseMethod(_:event:)), for: .touchDown)
check2.addTarget(self, action: #selector(HubEntriesTableViewController.CloseMethod1(_:event:)), for: .touchDown)

// Configure the cell...

return cell
}

Answer

Perhaps finally found an issue. When I reproduced the problem in my project, I realised that downcasting to UIButton was missing.

So within HubEntryTableViewCell subclass update the method like this:

@IBAction func plus(sender: AnyObject) {

    // self.tag, if called from UITableViewCell subclass, is rather cell's tag, not button's tag

    let button = sender as! UIButton
    print("button.tag = \(button.tag)")
    ...
}
Comments