How to give different tags to buttons in different TableView cells in Swift
Asked Answered
B

2

6

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
}
Bisutun answered 1/10, 2016 at 10:53 Comment(5)
Share our paste your entire code with what you are doing in button clickPalais
I'm referring to a database, with child coming from the tag of the pressed button. Something like this: let ref = FIRDatabase.database().referance().child("self.tag"), but tag is always 0 in my caseBisutun
set cell.buttonPlus.Tag = indexpath.row+UniqueNumber set cell.buttonMinus.Tag = indexpath.row+UniqueNumber(different) And you can get it easily.Juryman
@DevThakur can you be more specific? what is uniqueNumber and buttonPlusTag? are they different variables?Bisutun
Like For minus button Unique number may be (1000) and for plus i will use (5000) now i can set tag like cell.plusbutton.tag = indexpath.row+(5000) and when i will get it i can decrease button.tag by uniqueNumber Example : tag will be 50001 (for indexpath.row ==1) newTag = btnTag-(UniqueNumber)Juryman
R
2

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)")
    ...
}
Retha answered 1/10, 2016 at 11:4 Comment(2)
I have only one sectionBisutun
It properly show the indexpath.rows as 0,1,2 and so on. There is no problem with that. Also when I 'print(cell.plusButton.tag)' it gives properly 0,1,2... @RethaBisutun
A
0

If you have perform action on button click in tableview then try this code you don't worry about tag ..

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier("Eventcell", forIndexPath: indexPath)
   let check1: UIButton = (cell.viewWithTag(11) as! UIButton)
   let check2: UIButton = (cell.viewWithTag(12) as! UIButton)   
    check1.addTarget(self, action: #selector(EventListController.CloseMethod(_:event:)), forControlEvents: .TouchDown)
    check2.addTarget(self, action: #selector(EventListController.CloseMethod1(_:event:)), forControlEvents: .TouchDown)
    return cell
 }
  @IBAction func CloseMethod(sender: UIButton, event: AnyObject) {
        let touches = event.allTouches()!
        let touch = touches.first!
        let currentTouchPosition = touch.locationInView(self.Eventlisttable)
        let indexPath = self.Eventlisttable.indexPathForRowAtPoint(currentTouchPosition)!
        print("\(Int(indexPath.row))")

  }
  @IBAction func CloseMethod1(sender: UIButton, event: AnyObject) {
        let touches = event.allTouches()!
        let touch = touches.first!
        let currentTouchPosition = touch.locationInView(self.Eventlisttable)
        let indexPath = self.Eventlisttable.indexPathForRowAtPoint(currentTouchPosition)!
        print("\(Int(indexPath.row))")
 }

If my answer help you then give vote. thank you..

Antispasmodic answered 1/10, 2016 at 11:12 Comment(14)
All I want to do is increment and decrement the "point" value of entry from database, when the appropriate button is clicked. I mean when + button is pressed I want to increment by 1, and when minus is clicked the other way.Bisutun
then you can do this your operation in CloseMethod for that particular cell. In my case i have to perform some action in tableview for particular cell data ... my table is Eventlisttable .Antispasmodic
What are closeMethod and closeMethod1? are they for different buttons? And also cell.viewWithTag(11) and (12), what are those?Bisutun
yes both are different button in tableview and that button i access from tag .Antispasmodic
Can you look at the code I edited my original post. Should I do that code in CloseMethod func? If I use your method?Bisutun
yes this all code you have to put in closemethod. and this method call for only one cell so your particular one cell data update...Antispasmodic
In short your plus method code you have to put in my CloseMethod . got it ?Antispasmodic
what is Eventlisttable? It gives error has no member. And about selectors, it gives an error in there in EventListControllerBisutun
Eventlisttable is my table replace with your tablename and EventlistController is my controller replace it with your controllername.Antispasmodic
Okay, so these IBActions should be in my TableViewController or in my tableViewCell.swift file?Bisutun
IBAction is only buttonaction that perform some task like .Antispasmodic
It gives fatal error: unexpectedly found nil while unwrapping an Optional value when I try to run code in the code section: let check1: UIButton = (cell.viewWithTag(1) as! UIButton)Bisutun
Show me your this tableview method... func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { }Antispasmodic
I added my func to original question. It's in swift3 by the way.Bisutun

© 2022 - 2024 — McMap. All rights reserved.