如何从UITableViewCell中获取文本字段的值?

6

我有一个包含4个UITextFieldUITableView单元格,并且我想在按钮点击时获取它们的值。

这段代码无法检索任何值。

@IBAction func printBtnAction(_ sender: Any) {

    let cell = self.myTableView.dequeueReusableCell(withIdentifier: "manualAddC1") as! AddFriendC1Cell

    let alias = cell.aliasTextField.text!
    let primaryPhone = cell.primaryPhoneTextField.text!
    let secondaryPhone = cell.seondaryPhoneTextField.text!
    let email = cell.emailAddressTextField.text!

    print("Alias: \(alias), Phone: \(primaryPhone), Phone2: \(secondaryPhone), Email: \(email)")
}

这是TableView的截图。 图片描述

更多细节会很有用。 - Vince O'Sullivan
你能打印输出吗?出了什么问题?请详细解释。 - Jimmy James
请放置您的表视图截图。 - KAR
当我在文本字段中输入了值并打印出来时,仍然没有任何输出。 - Chris Mikkelsen
一如既往,请勿从视图(单元格)中获取数据,而应从模型(数据源数组)中获取。并且绝对不要在 cellForRow... 之外创建单元格。 - vadian
6个回答

22

我终于通过这个简单的解决方案弄清楚了。

@IBAction func saveBtnAction(_ sender: Any) {

    let index = IndexPath(row: 0, section: 0)
    let cell: AddFriendC1Cell = self.myTableView.cellForRow(at: index) as! AddFriendC1Cell
    self.alias = cell.aliasTextField.text!
    self.primaryPhone = cell.primaryPhoneTextField.text!
    self.secondaryPhone = cell.seondaryPhoneTextField.text!
    self.email = cell.emailAddressTextField.text!

    print("Alias: \(self.alias), Phone: \(self.primaryPhone), Phone2: \(self.secondaryPhone), Email: \(self.email)")
}

我忘了提到所有的文本字段都在第一个表格单元格部分和行(行:0,部分:0)中,而且我还有其他部分,但是除非我向下滚动,否则视图不会显示它。 - Chris Mikkelsen
如果有多行怎么办? - Krunal Nagvadia

14

好的。当你按下一个按钮时,你正在出队一个tableViewCell。

let cell = self.myTableView.dequeueReusableCell(withIdentifier: "manualAddC1") as! AddFriendC1Cell

我认为你想获取一个已存在的tableViewCell的引用,像这样:

   if let cell = tableView.cellForRow(at: indexPath) as? AddFriendC1Cell {
        // do what you need with cell
    }

即使这种方法可以工作,我也不建议使用这种方法。如果用户使用像 iPhone 4 这样的小屏幕手机,并且一些单元格在屏幕上不可见怎么办? 我认为在这种情况下,tableView.cellForRow 将返回不可见单元格的 nil

我建议在每个带文本字段的单元格中实现 textField:shouldChange,并将其委托给 tableView 的 viewController。当单元格中的文本更改时,委托应该将更改传播到 viewController,viewController 将把值保存到一个实例变量中。

然后,当你按下按钮时,你只需要从实例变量中获取值。


正确。这应该是原始的方法。 - Ankur Lahiry

1
第一步
在UITableViewCell中
import UIKit

@objc protocol TableViewDelegate: NSObjectProtocol{

    func afterClickingReturnInTextField(cell: ThirdTableCell)
}

class TableViewCell: UITableViewCell, UITextFieldDelegate {

    @IBOutlet weak var enterTextField: UITextField!
    weak var tableViewDelegate: TableViewDelegate?


    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
        enterTextField.delegate = self   
    }

    // @IBAction Of UITextfiled 
    @IBAction func tapHerre(_ sender: UITextField) {

        tableViewDelegate?.responds(to: #selector(TableViewDelegate.afterClickingReturnInTextField(cell:)))
        tableViewDelegate?.afterClickingReturnInTextField(cell: self)
    }

    // UITextField Defaults delegates
    func textFieldShouldReturn(_ textField: UITextField) -> Bool {

        enterTextField.resignFirstResponder()
        return true
    }
    func textFieldDidEndEditing(_ textField: UITextField) {

        enterTextField = textField
    }  
}

// 第二步

在UITableViewCell中

extension ViewController: UITableViewDelegate, UITableViewDataSource, TableViewDelegate {

    var valueToPass : String?

    func afterClickingReturnInTextField(cell: ThirdTableCell) {

        valueToPass = cell.enterTextField.text
    }

    func numberOfSections(in tableView: UITableView) -> Int {

        return 1
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

        return youArray.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableview.dequeueReusableCell(withIdentifier: "TableViewCell") as! TableViewCell
        cell.enterTextField.text = youArray[indexPath.row]
        cell.tableViewDelegate = (self as TableViewDelegate)
        return cell
    }
}

当键盘消失时,您可以在valueToPass中找到TextField的值。

0
在我看来,你应该在tableCell类中实现TextField代理方法,并在tableCell类中管理所有验证和输入文本。
现在,你需要获取所有输入的值,为此,你必须在tableCell类中使用协议,并使用代理将输入的值发送到viewController,同时使用标签来识别输入的是电话号码还是电子邮件等。
通过这种方式,你的代码将变得更简洁、结构化。
祝编码愉快!

0

我猜你的tableViewCells不是动态的。 你的cell方法应该长这样。

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
   let cell = tableView.dequeueReusableCell(withIdentifier: "YourCellID") as! YourClass
    cell.yourTextField.tag = indexPath.row
//
// Alias will be tag 0
// Primary Phone will be tag 1
// Secondary Phone will be tag 2 
// Email Address will be tag 3, so on and so forth
// Then, attach to each delegate
//
    cell.yourTextField.delegate = self
}

在你的UITableView处理类中(该类符合UITextFieldDelegate协议),请编写以下内容。
func textField(_ textField: UITextField, shouldChangeCharactersIn range:NSRange, replacementString string: String) -> Bool {
let kActualText = (textField.text ?? "") + string
switch textField.tag
{
case 0:
    aliasValueHolder = kActualText;
case 1:
    primaryPhoneValueHolder = kActualText;
case 2:
    secondaryPhoneValueHolder = kActualText;
case 3:
    emailAddressValueHolder = kActualText;
default:
    print("It is nothing");
}
return true;
}

然后您可以提交它。


在Swift中,不需要使用break关键字来结束switch语句,因为它与许多其他编程语言不同,不存在“fallthrough”现象。 - Eric Aya
@EricAya,我不是从Swift来的,在case后添加break并不会有任何坏处。这仍然是一种良好的编程实践。如果您在case或default中没有可执行语句,Swift仍然会发出警告。 - Cosmos Man

0
func textField(_ textField: UITextField, shouldChangeCharactersIn range:NSRange, replacementString string: String) -> Bool {
    //        let kActualText = (textField.text ?? "") + string

    var kActualText = (textField.text! as NSString).replacingCharacters(in: range, with: string)

    kActualText = kActualText.trimmingCharacters(in: .whitespaces)

    if textField.tag == 0
    {
        email_address = kActualText;
    }
    else if textField.tag == 3
    {
        password = kActualText;
    }
    else
    {
        print("It is nothing")
    }

    return true;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接