滚动后 UITableViewCell 标签发生变化[重复]

Posted

技术标签:

【中文标题】滚动后 UITableViewCell 标签发生变化[重复]【英文标题】:UITableViewCell tag changes after scrolling [duplicate] 【发布时间】:2018-01-09 18:15:22 【问题描述】:

我正在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

【问题讨论】:

This answer 类似的问题可能有用。 我不想收集所有文本字段值。我想检索特定的文本字段值并将其与其他文本字段值进行比较。假设我想检索第四行文本字段值并将其与第三行文本字段值进行比较,那么我将如何实现呢? 关键是你必须收集所有文本字段的值,然后才能将它们滚动出屏幕。否则单元格将被重复使用,标签将被更改,您将无法恢复 textField 值。 【参考方案1】:

这行不通有几个原因:

1) 重复使用表格视图单元格。因此,您获取第一项的单元格并将其分配为标签 1,但是当您滚动该单元格时,该单元格被重新用于说单元格 15(只是一个示例),并且您将标签分配为数字 15。现在具有标签的相同文本字段1 有标签 15。

2) 您正在表格视图中查找带有文本字段标签的视图,但该文本字段不是表格视图的子视图,它属于单元格,因此永远不会被发现。

编辑

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

(注意:这将永远不可用,我可能会在一周左右将其删除)

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

编辑

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

首先更改 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 = [:]

【讨论】:

那么,我现在该怎么办? 你真正想要达到什么目的?点击提交按钮时会发生什么? 我想从文本字段中获取价值。 是有一个提交按钮还是每个单元格一个?并且您想只在一个单元格或全部单元格中获取文本字段的值吗? 不,只有一个提交按钮。【参考方案2】:

您必须在单元格 forsizeitem 中分配 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

【讨论】:

我的文本字段计数可能会增加,所以这就是我没有使用 indexpath.row 作为标签的原因。我想使用我设置的标签找到特定的文本字段。 基本上当你的textfield增加时indexPath.row也会增加。 它完美适用于 100000000 行及更多行 是的,我知道。但我不想获得所有文本字段的值。我想使用标签查找特定的文本字段值。 你想达到什么目的?基本上你问“致命错误”这个问题解决了吗?如果是,那么我们继续前进并尝试解决第二个问题。

以上是关于滚动后 UITableViewCell 标签发生变化[重复]的主要内容,如果未能解决你的问题,请参考以下文章

使用我的 Android 应用程序将文本标签发送到 Instagram

UITableViewCell 滚动后数据变化

UIView.animateWithDuration 在滚动 uitableviewcell 后停止

UITableViewCell 背景图片滚动后消失

滚动后 UITableViewCell 内的 UIView 中的渐变发生了变化

滚动时更新 UITableViewCell