简体   繁体   中英

In swift, how to manage two buttons in same custom tableview cell?

I am trying to manage two buttons in same custom tableview cell. Added two buttons named Yes and No. If yes button is selected the No button will be inactive and Yes button became active.

Here is the image what I need

在此处输入图片说明

 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "tableCell") as! TableViewCell
    cell.yesButton.tag = 101
    cell.noButton.tag = 102
    cell.yesButton.addTarget(self, action: #selector(buttonClicked(sender:)), for: UIControl.Event.touchUpInside)
    cell.noButton.addTarget(self, action: #selector(buttonClicked(sender:)), for: UIControl.Event.touchUpInside)
    return cell
}

 @objc func buttonClicked(sender: AnyObject) {
    let buttonPosition = (sender as AnyObject).convert(CGPoint.zero, to: tableList)
    let indexPath = tableList.indexPathForRow(at: buttonPosition)
    if sender.tag == 101 {
        if indexPath != nil {
            print("Cell indexpath = \(String(describing: indexPath?.row))")
        }
    }

    if sender.tag == 102 {
        if indexPath != nil {
            print("Cell indexpath = \(String(describing: indexPath?.row))")
        }
    }
}

Create a model to main the state of yesButton and noButton for each tableViewCell, ie

class Model {
    var isYesSelected = false
    var isNoSelected = false
}

Create a custom UITableViewCell with Outlets of yesButton and noButton .

Create a single @IBAction for both the buttons and handle their UI based on which button is tapped.

Also, use a buttonTapHandler to identify the row in which the button is tapped. It will be called everytime a button is tapped. We'll be setting this when creating the instance of TableViewCell in tableView(_:cellForRowAt:) .

class TableViewCell: UITableViewCell {
    @IBOutlet weak var yesButton: UIButton!
    @IBOutlet weak var noButton: UIButton!

    var buttonTapHandler: (()->())?
    var model: Model?

    override func prepareForReuse() {
        super.prepareForReuse()
        yesButton.backgroundColor = .gray
        noButton.backgroundColor = .gray
    }

    func configure(with model: Model) {
        self.model = model
        self.updateUI()
    }

    @IBAction func onTapButton(_ sender: UIButton) {
        model?.isYesSelected = (sender == yesButton)
        model?.isNoSelected = !(sender == yesButton)
        self.updateUI()
    }

    func updateUI() {
        yesButton.backgroundColor = (model?.isYesSelected ?? false) ? .green : .gray
        noButton.backgroundColor = (model?.isNoSelected ?? false) ? .green : .gray
    }
}

UITableViewDataSource's tableView(_:cellForRowAt:) method goes like,

let numberOfCells = 10
var models = [Model]()

override func viewDidLoad() {
    super.viewDidLoad()
    (0..<numberOfCells).forEach { _ in
        self.models.append(Model())
    }
}

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

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "tableCell", for: indexPath) as! TableViewCell
    cell.configure(with: models[indexPath.row])
    cell.buttonTapHandler = {
        print(indexPath.row)
    }
    return cell
}

To get the totalPoints , count the models with isYesSelected = true , ie

let totalPoints = models.reduce(0) { (result, model) -> Int in
    if model.isYesSelected {
        return result + 1
    }
    return 0
}
print(totalPoints)

如下所示,使用您的标签获取该按钮,然后,您可以根据需要更改值。

var tmpButton = self.view.viewWithTag(tmpTag) as? UIButton

Simple 3 step process...!!

  1. Define Model Class
  2. Prepare tableView Cell & handle actions
  3. Set up tableView in view controller

Let's start implementation:

1) Define Model Class

In UI, we have a information like question & it's answer (Yes/No). So design model respectively.

//MARK:- Class Declaration -
class Question {
      let questionText: String
      var answerState: Bool?

      init(question: String) {
           self.questionText = question
      }
}

2. Prepare tableView Cell & handle actions

Create a custom tableView cell with Question Label , Yes Button & No Button . Link that view with respected @IBOutlets & @IBActions.

import UIKit

class TableViewCell: UITableViewCell {
      @IBOutlet weak var questionLabel: UILabel!
      @IBOutlet weak var yesButton: UIButton!
      @IBOutlet weak var noButton: UIButton!

      var question: Question?
      var toggle: Bool? {
          didSet {
                 question?.answerState = toggle
                 //Do buttons operations like...
                 if let isToggle = toggle {
                    yesButton.backgroundColor = isToggle ? .green : .gray
                    noButton.backgroundColor = isToggle ? .gray : .green
                 } else {
                    yesButton.backgroundColor =  .gray
                    noButton.backgroundColor = .gray
                 }
          }
      }

      func prepareView(forQuestion question: Question) {
           self.question = question
           questionLabel.text = question.questionText
           toggle = question.answerState
      }

      //Yes Button - IBAction Method
      @IBAction func yesButtonTapped(_ sender: UIButton) {
            toggle = true
      }

      //No Button - IBAction Method
      @IBAction func noButtonTapped(_ sender: UIButton) {
            toggle = false
      }
}

3. Set up tableView in view controller

class ViewController: UIViewController {

    //Prepare questions model array to design our tableView data source
    let arrQuestions: [Question] = [Question(question: "Do you speak English?"), Question(question: "Do you live in Chicago?")]
}

//MARK:- UITableView Data Source & Delegate Methods -
extension ViewController: UITableViewDataSource, UITableViewDelegate {

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

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        guard let tableViewCell = tableView.dequeueReusableCell(withIdentifier: "TableViewCell") as? TableViewCell else {
            return UITableViewCell()
        }
        tableViewCell.prepareView(forQuestion: arrQuestions[indexPath.row])
        return tableViewCell
    }

    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return 80.0
    }
}
  • Create basic tableView and configure dataSource functions 图片1

  • Create tableView cell with two buttons image2

  • Create cell class with buttons outlets and actions image3

  • Result of this code

结果gif

Enjoy!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM