从Swift中TableView动态单元格的文本字段读取数据
我想读取表视图中动态单元格中文本字段中的文本 每个单元格有两个文本字段,用户可以添加更多单元格 我的问题: 如何从文本字段(textField1和textField2)读取值并将其添加到我的cards结构中 在Cards结构中有两个变量。前标签和后标签为字符串 我的表格视图:从Swift中TableView动态单元格的文本字段读取数据,swift,tableview,swift5,custom-cell,Swift,Tableview,Swift5,Custom Cell,我想读取表视图中动态单元格中文本字段中的文本 每个单元格有两个文本字段,用户可以添加更多单元格 我的问题: 如何从文本字段(textField1和textField2)读取值并将其添加到我的cards结构中 在Cards结构中有两个变量。前标签和后标签为字符串 我的表格视图: class AddFCViewController: UIViewController { var numberOfTextFields = 1 var cards = [Cards]()
class AddFCViewController: UIViewController {
var numberOfTextFields = 1
var cards = [Cards]()
// Table View
let tableView : UITableView = {
let tableView = UITableView()
tableView.translatesAutoresizingMaskIntoConstraints = false
tableView.backgroundColor = .purple
return tableView
}()
// Add Button
let addButtton : UIButton = {
let btn = UIButton()
btn.translatesAutoresizingMaskIntoConstraints = false
btn.backgroundColor = .link
btn.setTitle("Ekle", for: .normal)
return btn
}()
override func viewDidLoad() {
super.viewDidLoad()
configureTableView()
configureAddButton()
}
// MARK: - Configure Add Button
func configureAddButton() {
view.addSubview(addButtton)
addButtton.addTarget(self, action: #selector(addButtonTapped(sender:)), for: .touchUpInside)
}
// MARK: - Add Button Tapped MEthod
@objc func addButtonTapped(sender: UIButton){
numberOfTextFields += 1
tableView.reloadData()
}
// MARK: - Configure Table View
func configureTableView() {
view.addSubview(tableView)
setTableViewDelegates()
tableView.rowHeight = 100
tableView.register(AddFCCell.self, forCellReuseIdentifier: "AddFCCell")
}
// MARK: - Table View Delegates
func setTableViewDelegates() {
tableView.delegate = self
tableView.dataSource = self
}
}
// MARK: - Table View Extension & Delegate Methods
extension AddFCViewController: UITableViewDelegate, UITableViewDataSource, UITextFieldDelegate {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return numberOfTextFields
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "AddFCCell") as! AddFCCell
cell.selectionStyle = .none
cell.textField1.tag = indexPath.row
cell.textField2.tag = indexPath.row
print(cell.textField1.tag)
print(cell.textField2.tag)
// cell.textField1.text = cards[indexPath.row].frontLabel
// cell.textField2.text = cards[indexPath.row].backLabel
cell.textField1.delegate = self
cell.backgroundColor = .purple
return cell
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 10
}
func textFieldDidBeginEditing(_ textField: UITextField) {
// textField.addTarget(self, action: #selector(valueChanged), for: .editingChanged)
}
}
这是我的自定义单元类
class AddFCCell: UITableViewCell {
// MARK: - Text Field 1
let textField1 : UITextField = {
let textField = UITextField()
textField.translatesAutoresizingMaskIntoConstraints = false
textField.backgroundColor = .white
textField.isUserInteractionEnabled = true
textField.placeholder = "TYPE HERE SOMETHING"
textField.font = UIFont.systemFont(ofSize: 20)
return textField
}()
// MARK: - Text Field 2
let textField2 : UITextField = {
let textField = UITextField()
textField.translatesAutoresizingMaskIntoConstraints = false
textField.backgroundColor = .white
textField.isUserInteractionEnabled = true
textField.placeholder = "TYPE HERE SOMETHING"
textField.font = UIFont.systemFont(ofSize: 20)
return textField
}()
// MARK: - view Did Load
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
contentView.addSubview(textField1)
contentView.addSubview(textField2)
configureTextBox1(textField: textField1)
configureTextBox2(textField: textField2)
}
// MARK: - Configure Text Box 1 Function
func configureTextBox1(textField : UITextField) {
textField.layer.cornerRadius = 20
}
// MARK: - Configure Text Box 2 Function
func configureTextBox2(textField : UITextField) {
textField.layer.cornerRadius = 20
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
PS-我删除了一些约束代码,因为那里的代码太多了。我会修改一些东西 1.去掉
numberOfTextFields
2.使用var cards=[cards]()
返回tableView中的单元格数
3.使用单个cards
实例初始化cards
,并将其属性设置为nil。所以我会把卡片作为实现
struct Cards {
var frontLabel: String?
var backLabel: String?
}
4.将卡初始化为
var cards = [Cards()]
5。返回数组计数中的行数
func numberOfSections(in tableView: UITableView) -> Int {
return cards.count
}
6.我会将文本字段委托职责迁移到单元格,而不是将其移动到ViewController,并且我会在AddFCCell
中有一个委托来更新ViewController中的文本更改
@objc protocol AddFCCellDelegate {
func updateCard(with frontText: String?, backText: String?, for cell: AddFCCell)
}
class AddFCCell: UITableViewCell {
weak var delegate:AddFCCellDelegate?
//.... other codes of yours
}
extension AddFCCell: UITextFieldDelegate {
func textFieldDidEndEditing(_ textField: UITextField) {
self.delegate?.updateCard(with: self.textField1.text, backText: self.textField2.text, for: self)
}
}
7.最后,在viewController中执行/确认添加FCcellDelegate
,并重新加载TableView bu更新文本
extension ViewController: AddFCCellDelegate {
func updateCard(with frontText: String?, backText: String?, for cell: AddFCCell) {
guard let indexPath = self.tableView.indexPath(for: cell) else {
return
}
self.cards[indexPath.row].frontLabel = frontText
self.cards[indexPath.row].backLabel = backText
self.tableView.reloadRows(at: [indexPath], with: .automatic)
}
}
8.更新cellforrowatinexpath
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "AddFCCell") as! AddFCCell
cell.selectionStyle = .none
cell.delegate = self
cell.textField1.text = cards[indexPath.row].frontLabel
cell.textField2.text = cards[indexPath.row].backLabel
cell.backgroundColor = .purple
return cell
}
显然,您可以实现一个高效的协议,并根据修改的textField n all返回/更新Cards struct中的特定变量,但这里发布的代码只是为了给您一个想法,让您开始使用
编辑1:
确保已正确设置TextFields代理
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
contentView.addSubview(textField1)
textField1.delegate = self
contentView.addSubview(textField2)
textField2.delegate = self
configureTextBox1(textField: textField1)
configureTextBox2(textField: textField2)
}
您可以将占位符文本添加到两个文本字段中,确保两个占位符文本不同,这里我尝试将uniq标识符分配给带有标记的文本字段 & 通过比较textFieldDidBeginEditing中的占位符文本来检索文本字段值 cell.textField1.tag=indexPath.row cell.textField2.tag=indexPath.row cell.textField1.placeholder=“1” cell.textField2.placeholder=“2” func textField didbeginediting(textField:UITextField){ }
这不是一个合适的解决方案,但是通过这种方式,您可以区分两个文本文件,并带有相同的标记。“何时我如何从文本字段读取值?”?当用户点击某个特定按钮或当用户停止编辑文本字段时?很抱歉丢失信息。当用户完成编辑后,我想读取数据。谢谢Sandeep。你的回答肯定让我进步了,但是我仍然无法访问那些文本字段值。我用您的答案更新了我的代码,并对其进行了调试,Cards对象textFields返回nil值@evrim demir:显示您的单元格代码,并设置断点,检查您的文本字段代理是否在单元格上触发(在此之前,请确保您已将单元格设置为textfields代理)。这是我的单元格代码,我确认在单元格中触发了代理@evrim demir:您没有做我在回答中提到的任何事情,希望代码能正常工作?1.您正在将textfields delegate设置为ViewController,我已经删除了check
cellForRowAt
方法,我已经清楚地删除了cell.textField1.delegate=self
和textField2。您尚未将ViewController设置为cellcell.delegate=self
checkcellForRowAt
3的代理。您没有将单元格设置为textfields delegate checkinit
method ofAddFCCell
显然我添加了textField1.delegate=self
如果没有设置这些内容,它将如何工作?@evrim demir:如果数据源中存在不一致,则会发生这种情况,就像您在阵列中添加了一张卡,但尚未重新加载tableview,或者如果您删除了一张卡,但尚未更新tableview,在这种情况下,tableview的单元格索引路径将过时,从而导致这些崩溃,您必须小心解决这些问题,显而易见的简单解决方案是调用self.tableview.reloadData()
而不是self.tableView.reloadRows(位于:[indexath],带:.automatic)
但是如果行数相当少,并且没有时间分析问题,那么这将是无效的
if(textField.tag && placeholder){
}