从 Swift 中的 TableView 动态单元格中的文本字段读取数据

Read Data From Text Field in TableView Dynamic Cell in Swift

我想阅读 table 视图中动态单元格文本字段中的文本。

每个单元格都有两个文本字段,用户可以添加更多单元格。

我的问题: 如何从文本字段(textField1 和 textField2)中读取值并将它们添加到我的卡片结构中?

在 Cards 结构中有两个变量。 frontLabel 和 backLabel 作为字符串

我的 table 查看:

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)
    }
   
  
    
}

这是我的自定义 Cell Class。

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]()到returntableView的单元格数

3. 使用单个 Cards 实例初始化 cards 并将其 属性 设置为 nil。所以我会将 Cards 实现为

struct Cards {
    var frontLabel: String?
    var backLabel: String?
}

4.初始化cards数组为

var cards = [Cards()]

5. Return 数组中的行数 count

    func numberOfSections(in tableView: UITableView) -> Int {
        return cards.count
    }

6. 我会将文本字段委托职责迁移到 Cell,而不是将其移动到 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. 最后,implement/confirm 到 viewController 中的 AddFCCellDelegate 并重新加载 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.更新CellForRowAtIndexPath

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
    }

你显然可以实现一个高效的协议和 return/update Cards struct 中的特定变量,基于它修改了所有的 textField,但是这里发布的代码只是为了给你一个想法并开始使用

编辑 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 textFieldDidBeginEditing(_ textField: UITextField) {

      if(textField.tag && placeholder){
      }

 }

这不是一个合适的解决方案,但通过这种方式,您可以区分使用相同标签提交的两个文本。