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

问题描述:

对于Clarity,我有一个 UIView控制器,顶视图包含 textfield 。我还有一个 tableview ,每行包含1 textfield

For Clarity I have a UIView Controller with a top view containing a textfield. I also have a tableview below that each row containing 1 textfield.

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

The problem: When I "didEndEditing" ANY of the textfields this means the one in the top view AND the ones in the tableview I want to save this information to core data and reload the tableview.

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

This works perfectly, EXCEPT! When I Select a textfield (anywhere) enter a value, then from being selected in one textfield, select another textfield. This causes a keyboard to become stuck that will never disappear.

我已经诊断出这是因为当调用DidEndEditing时,由于单元格的原因,我输入了刚刚选中的文本字段(键盘已启动)正在重新加载。

I have diagnosed that this is because when "DidEndEditing" is called I lose reference to the textfield i just selected (whos keyboard is up) due to the cell being reloaded.

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

Has anyone encountered this before? Did anyone find an elegant solution to reloading the data to a tableview cell while selecting a textfield inside of it?

编辑:我试过将 reloadData()移动到DidBeginEditing文本字段的功能,并成功获得选择指示器出现,但键盘也没有引用,即使我在 tableView.relaodData()$ c之后调用成为第一响应者$ c>

I have tried moving the reloadData() to the "DidBeginEditing" Function of the textfield, and successfully got the selection indicator to appear, but again the keyboard has no reference, even if i call become first responder after the tableView.relaodData()

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

I would avoid reloading the table view at all so that you don't disturb the first responder status of your text. You could either (1) insert and delete only what's changed or (2) redecorate cells that need updating.

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

So, instead of calling myTableView.reloadData(), figure out which index paths need to be added or removed and call the appropriate methods.

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



2。重新装修



这需要一种更模块化的方法来确定如何使单元格出列。而不是这样做:

2. Redecorating

This requires a more modular approach to how you are dequeuing cells. Instead of doing this:

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]
}

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

That way later on you can redecorate, i.e. update the content and configuration of the cells without reloading and disturbing the first responder status:

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