如何更改特定 TableViewCell 中的按钮颜色
Posted
技术标签:
【中文标题】如何更改特定 TableViewCell 中的按钮颜色【英文标题】:How to change Button color in specific TableViewCell 【发布时间】:2017-07-17 03:23:39 【问题描述】:我有一个类似测验应用的应用。在 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
当用户点击按钮时,我已经确定了表格视图的 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
这是它在故事板中的样子(如果有帮助)
【问题讨论】:
您需要在触摸按钮时更改颜色还是在选择时更改颜色? @ReinierMelian 当用户选择一个按钮时改变这个按钮的颜色。 你需要实现 isSelected 而不是 isHighlighted 属性来显示选择的颜色。 @Surjeet 我试过同样的问题。例如,当我在第一个单元格中按下第一个变体时,它会更改所有单元格中所有第一个变体的颜色 您需要将 selectedIndexPath 保存在一个变量中,并且在 cellForRowAt 函数中,您需要将 selectedIndexPath 与 indexPath 进行比较。如果两者相同,则只需要应用选定的颜色,否则应用普通颜色。 【参考方案1】:我认为您使用的代码比执行此任务所需的代码多得多,因此这是使用closures
的另一种方法,我的情节提要中只有一个viewController,并在其中添加了一个UITableView 和一个名为ButtonTableViewCell
的customCell然后我将一个普通的 UIButton 作为@IBOutlet 链接到该单元格,仅此而已,完整的实现在这里
https://github.com/rmelian2014/SOButtonsTableViewCellQuestion
已编辑
ButtonTableViewCell
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")
希望对你有帮助
【讨论】:
@АзаматБулегенов 不,您只需在情节提要中定义您的 customCell,如果您愿意,我可以发布图片来帮助您 它工作我试过谢谢。但是你能把你的代码编辑成 4 个按钮吗 @АзаматБулегенов 检查 repo github.com/rmelian2014/SOButtonsTableViewCellQuestion 并测试它,最好的问候 我想你没明白我的意思,一个单元格中应该有 4 个按钮 您可以使用部分,但我可以修改我的代码@АзаматБулегенов【参考方案2】:在您的 cellForRowAt indexPath: 方法中,您需要检查该行的 indexpath 是否与所选按钮的 indexpath 相同。如果相同,则需要显示突出显示的颜色,否则显示正常颜色。
所以将按下的按钮的索引路径保存在您的 buttonpressed 方法中的全局变量中。让变量被选中ButtonIndexPath。
在您的 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)
当然,当单击按钮以反映颜色的变化时重新加载您的表格视图。
更新 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
【讨论】:
我创建了全局变量 selectedButtonIndexPath 并将其等同于选定的按钮 indexpath 并将您编写的函数添加到 cellForRowAt 函数它不起作用。 好的,现在尝试理解这里的场景。您的每个单元格都有 4 个按钮变体 1-4。而且您的表格视图中是否还有多个单元格,每个单元格都有 4 个按钮?因为现在您的代码 deos 仅更改所选单元格的变体 1 的颜色。这是你想要达到的目标吗? 只是变体 1 只是对我的完美测试,我按下的按钮无关紧要,第一个或第四个按钮必须改变颜色。我刚刚编写了变体 1 进行测试,但它不起作用 你能解释一下是什么场景吗? globalIndexPath 将给出已单击的单元格,而不是在这种情况下的按钮。因此,除了保存之外,您还必须保存单击的按钮变体,然后您的 if 条件应该同时检查单元格索引路径和变体类型。 您可以按照 Reinier 提到的以下注释或在您现有的代码中,当您保存 globalIndexPath 时,保存所选按钮的标记,然后修改 if 语句以检查哪个标签被点击并改变它的颜色。因此必须进行 2 次检查。首先是使用索引路径单击的单元格,然后是被单击按钮的标记以上是关于如何更改特定 TableViewCell 中的按钮颜色的主要内容,如果未能解决你的问题,请参考以下文章
使用委托使用按钮更改 tableViewCell 内 UITextField 的值
按下 tableViewCell 中的按钮时打开一个新的 VC
在swift 3中的tableview中更新tableviewcell中的特定行?
我无法将 TableViewCell 按钮连接到 TableViewController!如何将 TableViewCell 中的值连接到 TableViewController?