Swift开发:点击按钮修改TableView新增行TextField文字颜色
嘿,我明白你现在遇到的问题啦——点击收入或支出按钮添加新行时,想让对应的TextField显示不同的文字颜色对吧?刚学Swift遇到这种UI联动的问题很正常,我来一步步帮你解决~
核心思路梳理
要实现这个需求,关键是给每一行数据标记类型(收入/支出),然后在创建Cell时根据类型设置TextField颜色,同时要注意TableView的Cell复用问题,避免颜色错乱。
具体实现步骤
1. 定义交易类型,给数据源加标记
首先,我们用枚举区分收入和支出,然后把数据源改成包含类型的数组:
// 先定义交易类型枚举 enum TransactionType { case income case expense } // 在你的ViewController里定义数据源数组 var transactions: [(title: String, amount: String, type: TransactionType)] = []
2. 处理按钮点击事件,添加对应类型的数据
点击两个按钮时,往数据源里添加对应类型的空数据,然后刷新TableView:
@IBAction func addIncomeTapped(_ sender: UIButton) { // 添加收入类型的空数据,后续用户可编辑 transactions.append((title: "", amount: "", type: .income)) tableView.reloadData() // 可选:自动滚动到新增行,方便用户编辑 let lastRowIndex = IndexPath(row: transactions.count - 1, section: 0) tableView.scrollToRow(at: lastRowIndex, at: .bottom, animated: true) } @IBAction func addExpenseTapped(_ sender: UIButton) { transactions.append((title: "", amount: "", type: .expense)) tableView.reloadData() let lastRowIndex = IndexPath(row: transactions.count - 1, section: 0) tableView.scrollToRow(at: lastRowIndex, at: .bottom, animated: true) }
3. 在Cell创建时根据类型设置文字颜色
在cellForRowAt方法里,根据当前行的交易类型,给TextField设置对应颜色,同时处理Cell复用的问题:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { // 注意这里的Cell标识符要和你Storyboard里的一致 let cell = tableView.dequeueReusableCell(withIdentifier: "MySecondCell", for: indexPath) as! MySecondCell let currentTransaction = transactions[indexPath.row] // 填充TextField的现有内容 cell.budgetTitle.text = currentTransaction.title cell.budgetAmount.text = currentTransaction.amount // 根据类型设置文字颜色 switch currentTransaction.type { case .income: cell.budgetTitle.textColor = .systemGreen // 收入用绿色 cell.budgetAmount.textColor = .systemGreen case .expense: cell.budgetTitle.textColor = .systemRed // 支出用红色 cell.budgetAmount.textColor = .systemRed } // 别忘了设置TextField的代理(如果需要处理编辑逻辑的话) cell.budgetTitle.delegate = cell cell.budgetAmount.delegate = cell return cell }
4. (可选)处理用户编辑TextField后的数据源更新
为了避免滚动后编辑的内容丢失,我们可以在Cell里加闭包,把编辑后的内容传回ViewController:
在你的MySecondCell类里添加:
class MySecondCell: UITableViewCell, UITextFieldDelegate { @IBOutlet weak var budgetTitle: UITextField! @IBOutlet weak var budgetAmount: UITextField! // 定义闭包用于传递编辑内容 var onTitleUpdated: ((String) -> Void)? var onAmountUpdated: ((String) -> Void)? override func awakeFromNib() { super.awakeFromNib() // 监听TextField编辑变化 budgetTitle.addTarget(self, action: #selector(titleChanged(_:)), for: .editingChanged) budgetAmount.addTarget(self, action: #selector(amountChanged(_:)), for: .editingChanged) } @objc private func titleChanged(_ textField: UITextField) { onTitleUpdated?(textField.text ?? "") } @objc private func amountChanged(_ textField: UITextField) { onAmountUpdated?(textField.text ?? "") } // 处理return键收起键盘 func textFieldShouldReturn(_ textField: UITextField) -> Bool { textField.resignFirstResponder() return true } }
然后在cellForRowAt里设置闭包:
// 在之前的cellForRowAt方法里添加这段 cell.onTitleUpdated = { [weak self] newTitle in guard let self = self else { return } self.transactions[indexPath.row].title = newTitle } cell.onAmountUpdated = { [weak self] newAmount in guard let self = self else { return } self.transactions[indexPath.row].amount = newAmount }
最后检查几个关键点
- 确保Storyboard里的Cell标识符和代码里的
"MySecondCell"完全一致 - 确认两个按钮的
IBAction已经正确连接到ViewController - 确保TableView的数据源和代理已经设置(可以在Storyboard里拖线,或者代码里设置
tableView.dataSource = self、tableView.delegate = self)
内容的提问来源于stack exchange,提问作者user9606399
相关产品推荐
相关产品推荐

