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