滚动后 UITableViewCell 标签发生变化

UITableViewCell tag changes after scrolling

我正在 UITableView 中创建一个表单。此表单在原型单元格中有一个 UILabelUITextField。每个 UITextField 都有一个独特的标签。 当用户点击提交按钮时,我想使用标签从每个 UITextField 中获取价值。
现在的问题是我有 18 UITextField,当我在字段中输入值并滚动视图以填充剩余字段时,在我按下提交按钮时填充数据后,应用程序崩溃了。它将无法找到第一个 UITextField.

的标签

我想比较 UITextFields 值。但我不想收集所有文本字段的值。我想检索特定的文本字段值并将其与单击提交按钮时的其他文本字段值进行比较。

This is how my UITableView Looks

这是我的代码:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "SurveyFormTableViewCell", for: indexPath) as! SurveyFormTableViewCell

    var  pest_code = textfield_id_value[indexPath.row].pest_code
    var srno = textfield_id_value[indexPath.row].srno
    var inspection_no = textfield_id_value[indexPath.row].inspection_no

    cell.text_field.layer.cornerRadius = 3
    cell.text_field.layer.borderWidth = 1
    cell.text_field.addTarget(self, action:  #selector(tableFieldDidChange(_textField:)), for: .editingChanged)
    let id:Int = Int("\(srno)\(pest_code)\(inspection_no)")!
    cell.text_field.tag = id

    cell.label?.text =  struc_array[indexPath.item].pest
    cell.label?.numberOfLines = 0
    cell.label?.lineBreakMode = NSLineBreakMode.byWordWrapping
    cell.layer.borderWidth = 1

    return cell
}

@IBAction func submit_survey_clicked(_ sender: UIButton) {
    text_field =  self.table_view.viewWithTag(textfield_tag1) as! UITextField
    text_field2 =  self.table_view.viewWithTag(textfield_tag2) as! UITextField
}

您必须在单元格中为项目分配 indexPath.row。像这样

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "SurveyFormTableViewCell", for: indexPath) as! SurveyFormTableViewCell


    var  pest_code = textfield_id_value[indexPath.row].pest_code
    var srno = textfield_id_value[indexPath.row].srno
    var inspection_no = textfield_id_value[indexPath.row].inspection_no



        cell.text_field.layer.cornerRadius = 3
        cell.text_field.layer.borderWidth = 1
        cell.text_field.addTarget(self, action:  #selector(tableFieldDidChange(_textField:)), for: .editingChanged)
        let id:Int = Int("\(srno)\(pest_code)\(inspection_no)")!
        cell.text_field.tag = indexPath.row


        cell.label?.text =  struc_array[indexPath.item].pest
        cell.label?.numberOfLines = 0
        cell.label?.lineBreakMode = NSLineBreakMode.byWordWrapping
        cell.layer.borderWidth = 1

        return cell
}

由于以下几个原因,这不会起作用:

1) table 视图单元格被重复使用。所以你得到第一个项目的单元格并将它分配给标签 1 但是当你滚动时该单元格被重复用于说单元格 15(只是一个例子)并且你将标签分配给数字 15。现在具有标签的相同文本字段1 有标签 15.

2) 您正在 table 视图中查找带有文本字段标签的视图,但文本字段不是 table 视图的子视图,它属于单元格,所以永远找不到。

编辑

这是使用数据模型的一个非常基本的示例Basic Data Model Example

(注意:这不会永远可用,我可能会在一周左右的时间内删除它)

(另请注意:这是一个非常基本的示例,无论如何都不是具有适当验证等的最完整方法)。

编辑

如果您想为数据列表中的每个唯一条目制作一个已输入值的列表,您可以使用字典。这是一个基于您在评论中提供的详细信息的示例:

首先更改 textfieldId 结构,使其采用 Hashable 协议,因此可以像这样用作字典中的键:

struct textfieldId: Hashable {
    var srno:Int
    var pest_code:Int
    var inspection_no:Int

    var hashValue: Int {
        return srno.hashValue ^ pest_code.hashValue ^ inspection_no.hashValue
    }

    static func ==(lhs: textfieldId, rhs: textfieldId) -> Bool {
        return lhs.srno == rhs.srno && lhs.pest_code == rhs.pest_code && lhs.inspection_no == rhs.inspection_no
    }
}

然后定义一个字典来保存为每个数据项输入的详细信息,如下所示:

var enteredValues: [textfieldId: String] = [:]

现在,只要输入的文本发生变化,您就可以像这样将其存储在字典中:

self.enteredValues[id] = textEntered // Update for your project

要再次获取信息(例如更新单元格),请执行以下操作:

cell.textField.text = self.enteredValues[id] // Update for your project.

这样您就创建了一个字典,其中包含每个数据项所输入的唯一值。

如果您需要清除列表,您可以这样做:

self.enteredValues.removeAll()

或者像这样创建一个新实例:

self.enteredValues = [:]