5

I have a UILabel that is inside a TableView, I want to change the color of the UILabel to red on user tap. I am using a UITapGestureRecognizer and on tapping the UILabel I can get the content of the UILabel but I can't get the actual UILabel since to my knowledge you can't have parameters inside a UIGesture function.

This is my code and it will help clear things up

class HomeProfilePlacesCell: NSObject {

    var Post =  [String]()

    @objc func PostTap(_ sender: UIGestureRecognizer) {
        print(Post[(sender.view?.tag)!])
    }

    func HomeProfilePlaceTVC(_ tableView: UITableView, cellForRowAt indexPath: IndexPath, streamsModel : streamModel,HOMEPROFILE: HomeProfile, controller: UIViewController) -> UITableViewCell {

         let cell = tableView.dequeueReusableCell(withIdentifier: "HomeTVC", for: indexPath) as! HomeTVC

         let tapGesture = UITapGestureRecognizer(target: self, action: #selector(PostTap(_:)))
         tapGesture.delegate = self as? UIGestureRecognizerDelegate
         cell.post.addGestureRecognizer(tapGesture)

         cell.post.text = streamsModel.Posts[indexPath.row]
         cell.post.tag = indexPath.row
         Post = streamsModel.Posts

         return cell 
    }
}

My function there is PostTap whenever a user taps the UILabel which is the cell.post then I can read it's content inside PostTap but in order to change the color of that UILabel then I'll have to pass the let cell constant into the PostTap function.

Is there anyway I can do that or a work around ? I am new to Swift

dahiya_boy
  • 9,298
  • 1
  • 30
  • 51
user1591668
  • 2,591
  • 5
  • 41
  • 84
  • Use Delegates: https://stackoverflow.com/questions/39585638/get-indexpath-of-uitableviewcell-on-click-of-button-from-cell/39585749#39585749 – Bista Jan 30 '18 at 05:03
  • In your case: `call.delegate = controller` – Bista Jan 30 '18 at 05:06
  • Try this @objc func PostTap(_ sender: UIGestureRecognizer) { sender.view?.backgroundColor = .red } – Lenin Jan 30 '18 at 05:53

6 Answers6

3

Use TableView Delegates: [SWIFT 4.0]

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)
{
    let cell = tableView.cellForRowAtIndexPath(indexPath) as! <your Custom Cell>
    cell.<your CustomCell label name>.textColor = UIColor.red
    //OR
    cell.<your Customcell label name>.backgroundColor = UIColor.green
    tableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.None)
}

func tableView(tableView: UICollectionView, didDeselectItemAtIndexPath indexPath: NSIndexPath) 
{
    let cell = tableView.cellForRowAtIndexPath(indexPath) as! <your Custom Cell>

    // change color back to whatever it was
    cell.<your Customcell label name>.textColor = UIColor.black
    //OR
    cell.<your Customcell label name>.backgroundColor = UIColor.white
    tableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.None)
}
Raj Aryan
  • 363
  • 2
  • 15
2

Add tag to cell as indexPath.row

cell.tag = indexPath.row

Then

@objc func PostTap(_ sender: UIGestureRecognizer) {
     let cell = self.tableVIew.cellForRow(at: sender.tag) as! HomeTVC
      // Now you access your cell label here, and can do whatever you want

}
Taimoor Suleman
  • 1,588
  • 14
  • 29
  • This is fragile and will break if the tableview allows row reordering (or row insertion/deletion) – Paulw11 Jan 30 '18 at 07:44
  • This method will be called when you Tapp on it. Row Reordering will not break it – Taimoor Suleman Jan 30 '18 at 07:46
  • Say I have 5 cells on screen and their tags are 0-4. Now I remove the cell at row 3, causing a new cell to be displayed to fill the gap. I now haves cells on screen with the following tags; 0,1,2,4,5,5. You can specifically reset the tags in the didMove... method to handle that case I guess. – Paulw11 Jan 30 '18 at 07:49
  • after row deletion you have to reload the table view. When tableview is reloaded, cell for row is called again, and tags will automatically will be reset. – Taimoor Suleman Jan 30 '18 at 07:52
  • But that results in a poor visual experience and unnecessary work in reloading the whole tableview. Trust me, there is always a better solution than using the tag. What if your tableview has sections for example? Tags break in so many ways. – Paulw11 Jan 30 '18 at 07:54
1

you can make it possible by using

 tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: IndexPath)

when user tap on a cell this method called in this method do this

tableView.cellForRow(at: indexPath)

this will give you cell cast it as your cell class and now u can do anything with your label in that cell cell.label....

junaid
  • 193
  • 1
  • 16
1

To change the color of clicked index label first you need to declare on varible to identify the clicked position

var selectedCellIndex = "" // initialize as empty string

In you cellForRowAt

 func HomeProfilePlaceTVC(_ tableView: UITableView, cellForRowAt indexPath: IndexPath, streamsModel : streamModel,HOMEPROFILE: HomeProfile, controller: UIViewController) -> UITableViewCell {

         let cell = tableView.dequeueReusableCell(withIdentifier: "HomeTVC", for: indexPath) as! HomeTVC



         cell.post.text = streamsModel.Posts[indexPath.row]
         cell.post.tag = indexPath.row
         cell.post.isUserInteractionEnabled = true

          let tapGesture = UITapGestureRecognizer(target: self, action: #selector(PostTap(_:)))
         tapGesture.delegate = self as? UIGestureRecognizerDelegate
         cell.post.addGestureRecognizer(tapGesture)
         Post = streamsModel.Posts

         if self.selectedCellIndex == "\(indexPath.row)" {
            cell.post.text = UIColor.red
         } else {
            cell.post.text = UIColor.blue
         }

         return cell 
    }

In your Tap function

func PostTap(_ sender:UIGestureRecognizer){
    let tapView = gesture.view!
    let index = tapView.tag
    self. selectedCellIndex = "\(index)"
    self.YOUR_TABLE_NAME.reloadData()
 }

Hope this will help you

Ganesh Manickam
  • 2,113
  • 3
  • 20
  • 28
1

Try Closure approach in Cell:

In Custom Table View cell:

class HomeTVC: UITableViewCell {

    @IBOutlet weak var labelPost: UILabel!

    var callBackOnLabelTap: (()->())?

    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code

        let tapGesture = UITapGestureRecognizer(target: self, action: #selector(postTap(_:)))
        tapGesture.numberOfTapsRequired = 1
        tapGesture.delegate = self
        self.labelPost.addGestureRecognizer(tapGesture)
    }

    @objc func postTap(_ sender: UIGestureRecognizer) {
        self.callBackOnLabelTap?()
    }

    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)

        // Configure the view for the selected state
    }
}

Then in cellForRowAt indexPath :

func HomeProfilePlaceTVC(_ tableView: UITableView, cellForRowAt indexPath: IndexPath, streamsModel : streamModel,HOMEPROFILE: HomeProfile, controller: UIViewController) -> UITableViewCell {

     let cell = tableView.dequeueReusableCell(withIdentifier: "HomeTVC", for: indexPath) as! HomeTVC

     cell.callBackOnLabelTap = {
        cell.labelPost.backgroundColor = UIColor.black
    }

     return cell 
}
Amit
  • 4,837
  • 5
  • 31
  • 46
0

For me, I wanted the color for the label to change when the container cell of a label is tapped. You can select what color you want for the Label text, when tapped by selecting, Highlighted (in Attributes inspector) for Label. From drop down you can select the color you want to see when the cell was tapped.

Attributes Inspector: Highlighted Property for label

dee.ronin
  • 1,040
  • 12
  • 22
Lokesh Purohit
  • 523
  • 6
  • 9