0

I have a TableViewController that returns four cells. Each cell has three buttons in it. The cells themselves don't have any interaction or segues attached because I don't need the user to interact with the cells, just the three buttons in the cells.

I have an empty array called selections and if each button is pressed I want to append an item to that array. So far I can't find any method that will keep track of each button that's pressed.

What method can I put this code in?

if cell.yes.isSelected == true {
            firstChoice = 1
            selections.append(firstChoice)
            print(selections.count, selections.reduce(0, +))
        }

Such that it will work for ALL of the cells loaded by my TableViewController?

Paulw11
  • 108,386
  • 14
  • 159
  • 186
Z-Man Jones
  • 187
  • 1
  • 12

3 Answers3

1

First of all - you should keep information about pressed button in your ViewController - not inside the table cells. Table cells will be reused - and you will lose that information. Best way to do that will be to use a custom delegate between cells and TableViewController. While creating each cell, you make:

cell.delegate = self

and inside a cell when the buttons are pressed, you call this delegate methods - let's say didPressButton1 didPressButton2.

Also if you want to have this state to be persistent (for example to disable, enable some button) while creating cells in your TableViewController you need to pull existing data and apply it to the cell itself - again TableViewCells are reused.

Grzegorz Krukowski
  • 18,081
  • 5
  • 50
  • 71
1

In order to achieve what you want you need to create delegates for both the custom cell and button.

//here is the view controller class
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, CustomCellDelegate {

    var firstChoice = 0
    var selections = Array<Any>()

    @IBOutlet weak var tableView: UITableView!
        override func viewDidLoad() {
            super.viewDidLoad()


    }

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

        cell?.delegate = self

        return cell!
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 4
    }

    func cellButtonTapped(_ cell: CustomCell) {
        if cell.isSelected {
            firstChoice = 1
            selections.append(firstChoice)
        }
    }
 }

The custom cell class

protocol CustomCellDelegate {
    func cellButtonTapped(_ cell: CustomCell)
}

class CustomCell: UITableViewCell, CustomButtonDelegate {

    var delegate: CustomCellDelegate?

    @IBOutlet weak var button1: CustomButton!
    @IBOutlet weak var button2: CustomButton!
    @IBOutlet weak var button3: CustomButton!

    override func awakeFromNib() {
        super.awakeFromNib()

        button1.delegate = self
        button2.delegate = self
        button3.delegate = self
    }

    func buttonTapped() {
        self.isSelected = !self.isSelected

        if let delegate = delegate {
            delegate.cellButtonTapped(self)
        }
    }
}

And the custom button

protocol CustomButtonDelegate{
    func buttonTapped()
}

class CustomButton: UIButton {

    var delegate: CustomButtonDelegate?

    override func awakeFromNib() {
        super.awakeFromNib()

        self.addTarget(self, action: #selector(buttonTapped(_:)), for: .touchUpInside)
    }

    func buttonTapped(_ sender: AnyObject) {
        if let delegate = delegate {
            delegate.buttonTapped()
        }
    }
}

Both of them with their protocols

J. Koush
  • 1,028
  • 1
  • 11
  • 17
  • Why do I need the custom button class? – Z-Man Jones Nov 28 '16 at 17:36
  • Programmatically it's a much better way to create your custom classes, here we created a custom button with a delegate, so that when the user taps on a button the delegate method will be called and you can write the necessary code in it. Plus here we have three buttons on four cell how will the app know which button did the user tap, having three separate IBActions for each button isn't a good way to code. – J. Koush Nov 28 '16 at 19:49
0

I don't know your specification, but it seems you could add a different target to each button:

button1?.addTarget(self, action:#selector(self.button1Clicked), forControlEvents: .TouchUpInside)
...
button3?.addTarget(self, action:#selector(self.button3Clicked), forControlEvents: .TouchUpInside)

and then you could have:

func button1Clicked() {
    firstChoice = 1
    selections.append(firstChoice)
}

...

func button3Clicked() {
    firstChoice = 3
    selections.append(firstChoice)
}

This way if button number 1 get clicked, button1Clicked() is fired and you can do your work as intended.

LopesFigueiredo
  • 146
  • 1
  • 8