0

I have two buttons within each TableView cell. When one button is tapped I want to change its appearance AND the appearance of the other button. I figured out how to change the tapped button using the approach outlined here, but am struggling with adjusting the other button.

Current relevant code:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let cell:FeedbackTableViewCell = self.feedbackTableView.dequeueReusableCell(withIdentifier: "cell") as! FeedbackTableViewCell

    // Setup YES / NO Buttons
    cell.feedbackYesButton.addTarget(self, action: #selector(MainSearchViewController.feedbackYesButtonTapped(sender:)), for: .touchUpInside)
    cell.feedbackNoButton.addTarget(self, action: #selector(MainSearchViewController.feedbackNoButtonTapped(sender:)), for: .touchUpInside)

    cell.feedbackYesButton.tag = indexPath.row
    cell.feedbackNoButton.tag = indexPath.row

    return cell
}


func feedbackYesButtonTapped (sender:UIButton) {

    let yesButtonTag = sender.tag

    switch yesButtonTag {
    case 0:

        // If YES button was not selected or was NO, then save value as YES and turn button "on", plus turn NO button "off".
            turnFeedbackButtonOn(sender)
            turnFeedbackButtonOff(NOT SURE HOW TO HANDLE THIS?)
        }
    // Other cases handled accordingly.
    default:
        return
    }
}

//MARK: - Functions to change the appearances of feedback buttons 
func turnFeedbackButtonOn(_ button: UIButton) {

    button.setTitleColor(UIColor(red: 157/255, green: 249/255, blue: 88/255, alpha: 1 ), for: UIControlState())
    button.titleLabel?.font = UIFont(name: "Avenir-Black", size: 18)
}

func turnFeedbackButtonOff(_ button: UIButton) {

    button.setTitleColor(UIColor.black, for: UIControlState())
    button.titleLabel?.font = UIFont(name: "Avenir", size: 17)
}

I tried passing the other button through with the target buttons, but I get an error when trying this. It feels like this should work, but I'm no expert at Swift so would appreciate any help!

cell.feedbackYesButton.addTarget(self, action: #selector(MainSearchViewController.feedbackYesButtonTapped(cell.feedbackYesButton, otherButton:cell.feedbackNoButton)), for: .touchUpInside)

func feedbackYesButtonTapped (sender:UIButton, otherButton:UIButton) {

//...

}
Community
  • 1
  • 1
Ben
  • 3,346
  • 6
  • 32
  • 51
  • Why cant you handle in your `FeedbackTableViewCell` itself? – Santosh Oct 24 '16 at 19:41
  • I'm not sure how to do that or if I understand what you are suggesting. As far as I could figure out, I need to create a target for the buttons that calls another function. In that feedbackYesButtonTapped function I cannot access the entire cell. I also tried passing the entire tableViewCell to the feedbackYesButtonTapped function, but when I tried that approach I couldn't access the buttons for some reason. – Ben Oct 24 '16 at 19:51

1 Answers1

1

It would be a little easier if you handled the button events within the UITableViewCell's class instead, since you'd be able to easily reference the two buttons within there, but it's still possible to do what you want the way you're doing it:

First you'll want to get a reference to the cell after the button is pushed. It looks like you're setting the cell's row to be the button's tag, so I assume you've only got 1 section in that tableView. In that case you can get a reference to the cell by saying let cell = tableView.cellForRowAtIndexPath(NSIndexPath(forRow: button.tag, inSection: 0)). This return an optional, for obvious reasons, so you'll want to make sure to unwrap it safely. Then you can say turnFeedbackButtonOff(cell.feedbackNoButton) in the spot you were not sure how to handle it.

creeperspeak
  • 5,403
  • 1
  • 17
  • 38
  • Thanks for the feedback. I'm going to try that, but could you talk a little more about handling button events within the UITableViewCell's class? I'm using a xib, so that means adding the events to the awakeFromNib func? Then I should be able to access universally in the other class where I've loaded the UITableView? – Ben Oct 24 '16 at 20:08
  • You can go into your FeebackTableViewCell class file and add the button selectors in awakeFromNib if you like, so you'd end up doing this: self.feedbackYesButton.addTarget(self, action: #selector(self.feedbackYesButtonTapped(sender:)), for: .touchUpInside) self.feedbackNoButton.addTarget(self, action: #selector(self.feedbackNoButtonTapped(sender:)), for: .touchUpInside) – creeperspeak Oct 24 '16 at 20:12
  • Then just move your feebackYesButtonTapped and feedbackNoButtonTapped functions inside your FeedbackTableViewCell class file as well, so when you call your turnFeedbackButtonOn/Off functions you can just say turnFeedbackButtonOff(self.feedbackNoButton) or whatever. – creeperspeak Oct 24 '16 at 20:14
  • 1
    This also makes it so that you don't have to keep track of the button's tag at all. – creeperspeak Oct 24 '16 at 20:17
  • This is very helpful and it feels like I'm almost there, but am getting some errors. Besides the buttons, I need to adjust the value of other variables to keep track of what users select. Therefore, I would like to keep the functions outside the TableView class. I can point the buttons selectors from the UITableView class to them no problem, however.... – Ben Oct 24 '16 at 20:48
  • ...I'm still having trouble accessing the other button within the function. I tried the *let cell = tableView.cellForRowAtIndexPath(NSIndexPath(forRow: button.tag, inSection: 0))* in the function but I get an error "do not match any available overlords". I tried a bunch of different variations on that approach and still can't get it to work. Any other guidance? Sorry for being slow on this! – Ben Oct 24 '16 at 20:52
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/126553/discussion-between-creeperspeak-and-ben). – creeperspeak Oct 24 '16 at 20:53
  • Thanks creeperspeak! Final part I was missing was a slight Swift 3 difference. This worked for me *let yesIndexPath = NSIndexPath(row: yesButtonTag, section: 0)* and then *if let cell = feedbackTableView.cellForRow(at: yesIndexPath as IndexPath) as? FeedbackTableViewCell { ... }* – Ben Oct 24 '16 at 22:19