Ios 如何更改特定TableViewCell中的按钮颜色

Ios 如何更改特定TableViewCell中的按钮颜色,ios,swift,uitableview,uibutton,Ios,Swift,Uitableview,Uibutton,我有一个类似测验的应用程序。在tableViewCell中,有4个用于任务变体的按钮。当用户按下按钮时,我需要改变颜色,当我尝试改变按钮的颜色时,所有表视图单元格中按钮的颜色都会改变。但我只需要在我按下的地方改变。我已经尝试编写委托,但它给出了相同的结果这是我如何编写委托的代码: class CustomButton: UIButton { override var isHighlighted: Bool { didSet { if isHighlighted {

我有一个类似测验的应用程序。在tableViewCell中,有4个用于任务变体的按钮。当用户按下按钮时,我需要改变颜色,当我尝试改变按钮的颜色时,所有表视图单元格中按钮的颜色都会改变。但我只需要在我按下的地方改变。我已经尝试编写委托,但它给出了相同的结果这是我如何编写委托的代码:

class CustomButton: UIButton {

override var isHighlighted: Bool {
    didSet {
        if isHighlighted {
            backgroundColor = UIColor.lightGray
        } else {
            backgroundColor = UIColor.init(red: 34/255, green: 89/255, blue: 128/255, alpha: 1.0)
        }
    }
}
}

我已经为按钮添加了目标操作

var variant1 = UIButton()
var variant2 = UIButton()
var variant3 = UIButton()
var variant4 = UIButton()

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "finalCell")!
    variant1 = cell.contentView.viewWithTag(1) as! UIButton
    variant2 = cell.contentView.viewWithTag(2) as! UIButton
    variant3 = cell.contentView.viewWithTag(3) as! UIButton
    variant4 = cell.contentView.viewWithTag(4) as! UIButton


    if (numberOfVariants.count != 0) {
        let questionTextView = cell.contentView.viewWithTag(5) as! UITextView
        questionTextView.text = "\(Questions[indexPath.row].content!)"
        variant1.addTarget(self, action: #selector(self.variant1ButtonPressed), for: .touchUpInside)
        variant2.addTarget(self, action: #selector(self.variant2ButtonPressed), for: .touchUpInside)
        variant3.addTarget(self, action: #selector(self.variant3ButtonPressed), for: .touchUpInside)
        variant4.addTarget(self, action: #selector(self.variant4ButtonPressed), for: .touchUpInside)
          }
        return cell
    }
当用户单击to按钮时,我已经识别了table view的indexPath(如果有帮助):

    func variant1ButtonPressed(_ sender:AnyObject) {
    print("Variant1")
    let buttonPosition:CGPoint = sender.convert(CGPoint.zero, to:self.tableView)
    let indexPath = self.tableView.indexPathForRow(at: buttonPosition)
    let intIndexpath = Int((indexPath?.row)!)
    globalIndexPath = intIndexpath
}
func variant2ButtonPressed(_ sender:AnyObject) {
    let buttonPosition:CGPoint = sender.convert(CGPoint.zero, to:self.tableView)
    let indexPath = self.tableView.indexPathForRow(at: buttonPosition)
    let intIndexpath = Int((indexPath?.row)!)
    globalIndexPath = intIndexpath

}
func variant3ButtonPressed(_ sender:AnyObject) {
    let buttonPosition:CGPoint = sender.convert(CGPoint.zero, to:self.tableView)
    let indexPath = self.tableView.indexPathForRow(at: buttonPosition)
    let intIndexpath = Int((indexPath?.row)!)
    globalIndexPath = intIndexpath


}
func variant4ButtonPressed(_ sender:AnyObject) {
    let buttonPosition:CGPoint = sender.convert(CGPoint.zero, to:self.tableView)
    let indexPath = self.tableView.indexPathForRow(at: buttonPosition)
    let intIndexpath = Int((indexPath?.row)!)
    globalIndexPath = intIndexpath


}
这是它在故事板中的样子(如果有帮助的话)

cellForRowAt indexPath:方法中,需要检查行的indexPath是否与所选按钮的indexPath相同。如果相同,则需要显示高亮显示的颜色,否则为正常颜色

因此,在buttonpressedmethod中保存全局变量中按下的按钮的indexpath。让有效按钮在索引路径中选择

cellForRowAt indexPath:方法中添加以下代码

 if indexPath.row==selectedButtonIndexPath.row {
        backgroundColor = UIColor.lightGray
    } else {
        backgroundColor = UIColor.init(red: 34/255, green: 89/255, blue: 128/255, alpha: 1.0)
    }
当然,当单击按钮以反映颜色变化时,请重新加载tableview

更新1:

通过获取sender.tag,然后更改if条件,可以尝试在按钮按下方法中保存按钮的标记吗

if indexPath.row==selectedButtonIndexPath.row  {
    if buttonTag == 1{
        variant1.backgroundcolor = UIColor.lightGray
        variant2.backgroundColor = UIColor.init(red: 34/255, green: 89/255, blue: 128/255, alpha: 1.0)
        // and so on for all buttons.
    }else if buttonTag == 2{
        // same as above but for variant2
    }
} else {

}

我认为您使用的代码比执行此任务实际需要的代码多得多,因此这是使用
闭包
的另一种方法,我的故事板中只有一个viewController,在里面添加了一个UITableView和一个名为
ButtonTableViewCell
的自定义单元格,然后我将一个普通UIButton链接到该单元格作为@IBOutlet,仅此而已,全面实施就在这里

编辑 按钮式可视单元 视图控制器
希望这对您有所帮助

您需要在触摸按钮时更改颜色,或者在选择时更改颜色?@ReinierMelian当用户选择一个按钮时,请更改此按钮的颜色。您需要实现isSelected而不是isHighlighted属性来显示所选颜色。@Surjeet我尝试过相同的问题。例如,当我在第一个单元格中按下第一个variant时,它会更改所有单元格中所有第一个variant的颜色。您需要在变量中保留selectedIndexPath,在cellForRowAt func中,您需要将selectedIndexPath与indexPath进行比较。如果两者相同,则只需应用选定颜色,否则应用普通颜色。我创建了全局变量selectedButtonIndexPath,并将其等同于selected button indexpath,并添加了您编写到CellForRow函数的函数,但该函数不起作用。好了,现在尝试理解该场景。您的每个单元格有4个按钮1-4。在tableview中是否也有多个单元格,每个单元格有4个按钮?因为现在您的代码deos只是更改所选单元格变体1的颜色。这就是你想要实现的吗?只是变型1对我来说只是完美的测试,我按下的按钮不重要,第一个或第四个按钮必须改变颜色。我刚刚编写了变体1进行测试,但它不起作用。你能解释一下场景是什么吗。globalIndexPath将给出已单击的单元格,而不是本例中的按钮。因此,除了保存外,您还必须保存单击的按钮变量,然后您的if条件应同时检查单元格索引XPath和变量类型。保存globalIndexPath时,您可以按照Reinier或现有代码中提到的以下注释进行操作,同时保存所选按钮的标记,然后修改if语句以检查单击的标记并更改其颜色。因此,必须进行两项检查。首先,对于使用indexpath单击的单元格,然后是单击按钮的标记@АззззззззззззБззззззз107。但是你能把你的代码编辑成4个按钮吗?@АззааааБааааБаааааБаааааааа1072
    import UIKit

@IBDesignable
class ButtonTableViewCell: UITableViewCell {

    @IBInspectable var selectedColor : UIColor = UIColor.red
    @IBInspectable var normalColor : UIColor = UIColor.blue

    static let cellHeigth : CGFloat = 360

    @IBOutlet var buttonsArray: [UIButton]!
    var selectedText : String?{
        willSet{
            guard newValue != nil else{
                return
            }

            var foundedIndex = -1
            for (index,text) in self.texts.enumerated() {
                if(text == newValue!){
                    foundedIndex = index
                    break
                }
            }

            guard foundedIndex != -1 else
            {
                return
            }

            self.buttonsArray[foundedIndex].backgroundColor = selectedColor
        }
    }
    var texts : [String] = []

    var buttonActionClosure : ((_ selectedText:String?)->Void)?

    func setupWithClosure(texts:[String],textSelected:String?,closure:((_ selectedText:String?)->Void)?)
    {
        self.texts = texts

        for (index,button) in self.buttonsArray.enumerated(){
            if(self.texts.count > index)
            {
                button.setTitle(self.texts[index], for: .normal)
            }
            button.tag = index
            button.backgroundColor = self.normalColor
        }


        self.selectedText = textSelected
        if(closure != nil)
        {
            self.buttonActionClosure = closure
        }


    }

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

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

        // Configure the view for the selected state
    }

    @IBAction func buttonAction(sender:UIButton)
    {
        if(self.texts.count > sender.tag){
            let newSelectedText = self.texts[sender.tag]

            if(newSelectedText != self.selectedText){
                self.selectedText = newSelectedText
            }else
            {
                self.selectedText = nil
            }
        }
        if(self.buttonActionClosure != nil)
        {
            self.buttonActionClosure!(self.selectedText)
        }
    }

    override func prepareForReuse() {
        super.prepareForReuse()
        self.buttonActionClosure = nil
    }

}
import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var tableView: UITableView!

    var dictOfSelectedsCells : [Int:String?] = [:]

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        tableView.delegate = self
        tableView.dataSource = self
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }


}

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

    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return ButtonTableViewCell.cellHeigth
    }

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

        if let cell = tableView.dequeueReusableCell(withIdentifier: "ButtonTableViewCell", for: indexPath) as? ButtonTableViewCell
        {
            cell.selectionStyle = .none
            var selectedText : String?
            if let currentSelectedText = self.dictOfSelectedsCells[indexPath.row]
            {
                selectedText = currentSelectedText
            }

            cell.setupWithClosure(texts:["Variant1","Variant2","Variant3","Variant4"], textSelected: selectedText, closure: { [weak self] (selected) in
                debugPrint(indexPath)
                self?.dictOfSelectedsCells[indexPath.row] = selected
                tableView.reloadRows(at: [indexPath], with: .none)
            })

            return cell
        }
        assert(false, "this must not happen")
    }
}