如何更新UITableView,使单元格中的UITextField不会失去焦点

5
设置:表格有1个自定义单元格。此单元格有1个文本框。在每个文本框中输入数字。tableView有5行(使用此单元格)。如果我更改任何一个单元格中的数字,则需要更新所有单元格,我只需调用tableView.reloadData()即可。文本框中的更改使用editingDidEnd事件处理。
问题:我点击任何一个文本框并更改数字。然后,我单击另一个文本框以更改其值。首先调用editingDidEnd,重新计算所有值,并调用tableView.reloadData。现在,由于表已重新加载,第二个文本框的点击被忽略了。
我无法直接更新单元格,因为它们是自定义单元格,并且该值在该类内进行更改。我无法从自定义单元格类中更新所有单元格。
对于非母语英语的人来说,这是一个难以用书面语解释的问题。如果您理解这个问题,将不胜感激 :)。
使用Xcode 7.1和Swift。谢谢。
3个回答

4
调用reloadData时,所有的单元格都将从表视图中删除并重新添加。由于被删除了,所以它不再处于响应链中,这意味着它的文本字段不能成为第一个响应者(已选)。
有两个可行的选择。
记录选定的行,调用reloadData,然后对正确的行上的文本字段调用becomeFirstResponder
不要调用reload data,只需更新文本字段中的值。这个选项更取决于您的应用程序的层次结构。

如果这是我有的两个选择,那么我会选择第一个。第二个选项不可行,因为所有单元格都是自定义单元格,它们不知道彼此的状态值等信息。对于第一个选项,我不知道该单元格是否真正接收到了didSelectRowAtIndexPath方法。让我试一下并回复您。感谢您的建议。 - oyalhi
我可以在editingDidBegin事件中调用reloadData。这样就不会错过了。但我希望有更好的方法来处理这个问题。我所做的只是从一个textField简单地点击到另一个textField。 - oyalhi
第二个选项证明实现起来要简单得多。 - oyalhi
我也遇到了同样的问题,但即使在创建表格时调用becomeFirstResponder,它也不会实际选择那个文本字段。我还尝试过在重新加载表格的命令之后调用它,但是出现了错误的文本字段被调用的情况? - Nic Parmee
在创建tableview时调用becomeFirstResponder可能太早了。文本字段需要在视图层次结构中才能正常工作。您需要等到viewDidLayoutSubviewstableView(_: willDisplay: forRow:)被调用,以使单元格中的某些内容成为第一个响应者。 - Craig Siemens

2
这可能很简单,理想情况下,您可以存储要聚焦的字段的值和所讨论的单元格的索引路径(例如,在重新加载后再生成编辑字段时)。
这段代码应该有所帮助:
- (void)tableView:(UITableView *)tableView
  willDisplayCell:(UITableViewCell *)cell
forRowAtIndexPath:(NSIndexPath *)indexPath
{
    if(indexPath == self.editingIndexPath)
    {
        [self.editingTextField becomeFirstResponder];
    }
}

0
iOS更新UITableView而不重新加载
在以下情况下:
  • 更新带有UITextField的TableView单元格,同时不丢失焦点
func updateCell() {
    let cells = self.tableView.visibleCells
    for cell in cells {
        guard let cell = cell as? MyTableViewCell else {
            continue
        }
            
        guard let indexPath = self.tableView.indexPath(for: cell) else {
            return
        }
        
        //logic
    }
}

更新页眉/页脚而不重新加载部分。
func updateFooter(sectionIndex: Int) {
    guard let footerView = self.tableView.footerView(forSection: sectionIndex) as? MyFooterView else { return }

    UIView.setAnimationsEnabled(false)
    tableView.beginUpdates()

    //logic

    footerView.sizeToFit()

    tableView.endUpdates()
    UIView.setAnimationsEnabled(true)
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接