滚动 UITableView 时自定义单元格中的 UITextField 文本正在更改

Posted

技术标签:

【中文标题】滚动 UITableView 时自定义单元格中的 UITextField 文本正在更改【英文标题】:UITextField text in custom cell is changing while scrolling the UITableView 【发布时间】:2017-01-19 08:56:16 【问题描述】:

如果我在UITableView 中有很多帐户。当我滚动UITableView 时,我在第一个单元格中编辑的UITextFid 文本正在重置。这是因为单元格可重用性而发生的。我没有在 Indexpath 的 cellForRow 的 UITableView 中设置我的 UITextFid 文本。由于其他实现,我正在自定义单元格视图中执行此操作。

你能指导我吗?

STTableViewCell *cell;
cell =  [tableView dequeueReusableCellWithIdentifier:@"STTableViewCell"];

if (cell == nil)

    cell = [[STTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"STTableViewCell"];


cell.accountNameTxtField.delegate = self

// Fetching the URL from Array at index of indexpath.row
OTPAuthURL *url = [self.authURLs objectAtIndex:indexPath.row];

// Sending the generated authURl and token description to custom STTableViewCell to load the data in a tableView
[(STTableViewCell *)cell setAuthURL:url withtokenDesc:nil];

return cell;

【问题讨论】:

能否请您显示 cellForRowAtIndexPath 的代码? @AnoopNyati 我已经编辑了我的问题。请看一下 好的@Sadik!你从哪里得到文本?你说你设置了一些自定义方法?您如何为每个帐户/单元格映射文本? - (void)setAuthURL:(OTPAuthURL *)authURL withtokenDesc:(NSString *)tokenDesc self.accountNameTxtField.text = authURL.name; 您可以编辑我们的 setAuthURL:withTokenDesc 方法还是某种固定形式的方法? 【参考方案1】:

您将需要维护一个数组,其中对象数等于 tableview 中的项目数。 每个文本字段都应该有一个等于该行的 indexPath.row 的标签。 例如:

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
           let cell:CustomUITableViewCell = tableView.dequeueReusableCell(withIdentifier: "customCell")! as CustomUITableViewCell
                cell.textfield = indexPath.row
                cell.textfield.delegate = self
                cell.textfield.text = arrayTemp[indexPath.row] as String

    

使用文本字段的委托方法,您将拥有

   public func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool
     arrary[textfield.tag] = textfield.text

在文本字段委托方法中,您需要将文本保存在临时数组中与文本字段标记等效的索引处

【讨论】:

我在自定义单元格视图中添加文本,而不是在 cellForRowAtIndexPath 中。 创建它的属性并从cellForRowAtIndex访问它,再次检查cellForRowAtIndex代码【参考方案2】:

您需要将输入的文本存储为输入或失去焦点,一旦单元格被回收,信息将丢失。使用来自文本字段 textfieldDidEndEditing 的委托回调然后当单元格返回到视图中时,您需要检查之前是否存储了文本并重新填充它。

也可以尝试this method监听编辑事件

【讨论】:

如果我将值存储在 textfieldDidEndEditing like-self.accountNameTxtField.text = authURL.name;。当我的表格视图从编辑模式变为正常模式时,值值反映在 tbale 视图中。虽然我没有通过完成栏按钮操作将 vlaue 存储在我的钥匙串中。 是的,我的意思不是存储,您需要将其存储在文本字段本身以外的其他地方,因为当单元格被回收时self.accountNameTxtField.text 将被重置(假设这是在单元格),您需要以某种方式将其存储在单元格之外,只有您知道如何最好地做到这一点,因为我不知道您的程序的结构【参考方案3】:

设置cellForRowAtIndexPath中的值。这就是它的用途。这样做所有这些重复使用的东西就像魅力一样。

我对自定义视图所做的是: 在我的自定义视图类中,我创建了一些 bind(MyObject myObject) 方法(或 bind:(MyObject*)myObject 分别)。 bind 方法接收要显示为参数的对象(或多个参数)。 bind 方法然后执行所有自定义内容以便在单元格中显示对象,以便视图控制器(已实现 cellForRowAtIndexPath)不受任何自定义视图相关内容的影响,但 bind 方法除外。

我每次都在cellForRowAtIndexPath 中调用这个绑定方法。

【讨论】:

【参考方案4】:

看起来一切都按预期工作 - 而该单元格仍然显示。但是,每次一个单元格从显示屏上消失时,您都会重复使用这些单元格,因此信息会丢失。

您需要将数据模型和显示分开 - 如果您只有一个字段的文本,则创建一个字符串数组 (myTableData : [String]),并在 cellForRowAt 中将文本字段设置为 myTableData[indexPath.row]

如果您需要在表格中填充多个字段,则使用您需要的内容定义一个结构(或类),并使用该数组来填充表格

【讨论】:

【参考方案5】:

详细说明 Pankaj 的答案。

你可以像这样更新你的文本设置方法

- (void)setAuthURL:(OTPAuthURL *)authURL withtokenDesc:(NSString *)tokenDesc andTag:(NSInteger)tag

    self.accountNameTxtField.tag = tag;
    self.accountNameTxtField.text = authURL.name;

来自cellForRowAtIndexPath方法,不仅可以简单地设置文本,还可以用它设置标签。

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

    STTableViewCell *cell;
    cell =  [tableView dequeueReusableCellWithIdentifier:@"STTableViewCell"];

    if (cell == nil)
    
        cell = [[STTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"STTableViewCell"];
        cell.accountNameTxtField.delegate = self
    

    // Fetching the URL from Array at index of indexpath.row
    OTPAuthURL *url = [self.authURLs objectAtIndex:indexPath.row];

    // Sending the generated authURl and token description to custom STTableViewCell to load the data in a tableView, and setting unique tag for textfield
    [(STTableViewCell *)cell setAuthURL:url withtokenDesc:nil andTag:indexPath.row];

    return cell;

实现UITextFieldDelegate方法

- (BOOL)textFieldShouldReturn:(UITextField *)textField

    //Printing log to check tag
    NSLog(@"Tag = %ld",textField.tag);

    //Update the original array
    self.authURLs[textField.tag] = textField.text;

    //Dismiss keyboard
    [textField resignFirstResponder];

    return YES;

希望这会有所帮助!

【讨论】:

以上是关于滚动 UITableView 时自定义单元格中的 UITextField 文本正在更改的主要内容,如果未能解决你的问题,请参考以下文章

滚动时自定义 UITableViewCell 中的 UITextFields 文本出现在其他单元格中

单元格中的 UITableView 动画导致平滑滚动中断

滚动 UITableView 框架问题以查看单元格中的 UITextField?

编辑 tableView 时自定义单元格 imageView 移到左侧

重用 uitableview 单元格以及单元格中的子视图

具有调整大小的大图像的 UITableView 单元格中的初始滚动滞后?