如何在编辑表格视图单元格中的文本字段时重新加载所有表格视图单元格 - iOS Swift

Posted

技术标签:

【中文标题】如何在编辑表格视图单元格中的文本字段时重新加载所有表格视图单元格 - iOS Swift【英文标题】:How to reload all tableview cells, while editing a textfield in a tableview cell - iOS Swift 【发布时间】:2017-01-12 12:36:38 【问题描述】:

为了清楚起见,我有一个UIView Controller,其顶视图包含一个textfield。我还有一个tableview,每行包含1个textfield

问题:当我"didEndEditing" 任何文本字段时,这意味着顶部视图中的文本字段和表格视图中的文本字段我想将此信息保存到核心数据并重新加载tableview

这很完美,除了!当我选择一个文本字段(任何地方)输入一个值,然后从一个文本字段中被选中,选择另一个文本字段。这会导致键盘卡住,永远不会消失。

我已经诊断出这是因为当 "DidEndEditing" 被调用时,由于单元格被重新加载,我失去了对我刚刚选择的文本字段的引用(谁的键盘已打开)。

有没有人遇到过这种情况?有没有人找到一个优雅的解决方案来将数据重新加载到tableview cell,同时在其中选择textfield

编辑:我尝试将reloadData() 移动到文本字段的"DidBeginEditing" 函数,并成功使选择指示器出现,但键盘再次没有参考,即使我在@ 之后调用成为第一响应者987654332@

【问题讨论】:

尝试在键盘启动时重新加载数据,而不是在 UItextField Delegate 上加载。设置键盘打开和关闭的观察者。 【参考方案1】:

我会完全避免重新加载表格视图,以免打扰文本的第一响应者状态。您可以 (1) 仅插入和删除已更改的内容,或者 (2) 重新装饰需要更新的单元格。

1。插入和删除

因此,与其调用myTableView.reloadData(),不如找出需要添加或删除哪些索引路径并调用适当的方法。

myTableView.insertRows(at: newIndexPaths, with: .automatic)
myTableView.deleteRows(at: oldIndexPaths, with: .automatic)

2。重新装修

这需要一种更加模块化的方法来处理出列单元格的方式。而不是这样做:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
    let cell = tableView.dequeueReusableCell(withIdentifier: "myCell", for: indexPath)
    cell.data = dataArray[indexPath.row]
    return cell

这样做:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
    let cell = tableView.dequeueReusableCell(withIdentifier: "myCell", for: indexPath)
    decorate(cell, at: indexPath)
    return cell


func decorate(_ cell: UITableViewCell, at indexPath: IndexPath) 
    cell.data = dataArray[indexPath.row]

这样以后您可以重新装饰,即更新单元格的内容和配置,而无需重新加载和干扰第一响应者状态:

for cell in myTableView.visibleCells 
    if let indexPath = myTableView.indexPath(for: cell) 
        decorate(cell: cell, at: indexPath)
    

【讨论】:

问题是所有文本字段的占位符文本都依赖于所有其他文本字段,因此 relaodData() 对功能至关重要。我可以让它重新加载所有带有空文本字段的单元格,但这对我的问题没有帮助,因为用户可以选择其中一个并面临相同的错误。 这听起来更像是您的占位符文本依赖于数据模型中的数据,而不一定依赖于视图本身。视图不应该被用作事实的来源,它应该都源于模型。你能重构以不同的方式构造这个占位符文本吗? 嗯...你是对的,目前每当文本字段“didEndEditing”我将数据保存到我的dataModel,然后重新加载表格视图以更新占位符文本。如果有另一种方法可以在没有 tableView.relaodData() 的情况下更新每个单元格占位符文本,请分享? 我在答案中解释的重新装修方法听起来像你需要的。触发单元格中占位符更新的单元格配置应该从decorate(_:at:)调用,这样单元格在重新加载时进行配置,也可以在不重新加载的情况下进行配置,即“重新装饰”。 哦,我明白了!如果我通常的单元设置(比如添加 UIControl 事件 DidEndEditing 仍然在 CellForROw 中?)并且只将 cell.textfield.placeholder = dataArray[indexpath.row] 放在重新装饰中,我会尝试一下,只是有点混乱?我相信是这样,只是想确保我的想法是正确的【参考方案2】:

您是否尝试过在重新加载表格视图之前存储索引路径并使用它来查找单元格并将其中的文本字段设置为重新加载后的第一响应者?

【讨论】:

我以前用这个方法得到了一个解决方案,但它是 80% 正确的,因为有一种情况是我打开视图 -> 在 topView 文本字段中输入文本,然后去选择表格视图中的文本字段和此错误发生。在表格视图中选择文本字段后,该解决方案将完美运行。但是第一个边缘情况仍然是它的缺陷。 这个问题是,当我在表格视图单元格中选择该文本字段时,我的 editingDidBegin 没有被调用 -(void) tableView:(UITableView )tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath if([indexPath row] == ((NSIndexPath)[[tableView indexPathsForVisibleRows] lastObject]).row) //加载结束 //例如 [activityIndi​​cator stopAnimating]; 在你的代码中添加这个,并确保你将你的 textField 设置为第一响应者

以上是关于如何在编辑表格视图单元格中的文本字段时重新加载所有表格视图单元格 - iOS Swift的主要内容,如果未能解决你的问题,请参考以下文章

如何在 swift 4 中的另一个表视图控制器中获取该表视图单元格中的文本字段文本?

iOS:文本字段委托,如何在处理表格视图中的行移动之前自动结束编辑?

点击保存按钮并存储在字典中时获取表格视图单元格中的文本字段?

表格视图单元格中的标签和文本字段之间的空间相等。

如何在单击按钮时获取表格视图单元格中文本字段的值?

以编程方式开始在另一个表格视图单元格中编辑 UITextField