从textFieldDidEndEditing调用reloadData后,对UITableView的indexPath不正确

时间:2012-07-31 15:58:14

标签: objective-c uitableview uitextfield nsindexpath becomefirstresponder

因此,我试图模拟管理电话号码时标准Apple代码在联系人应用上的工作方式。具体来说,我正在努力从tableview中删除一行,如果它是空的并且用户导航到任何其他行

我的问题是,当tableview重新加载导致UITextField重新调整其响应者时,我需要再次为用户导航到的文本字段设置响应者

我有UITextField委托,正在处理通常的textFieldShouldBeginEditing , textFieldDidBeginEditing , textFieldShouldEndEditing , textFieldDidEndEditing

为了处理这些功能,我的代码在textFieldDidEndEditing内,我从tableview数组中删除了数据,并且由于tableview有2个部分,我正在调用:

[MyTableView reloadSections:[NSIndexSet indexSetWithIndex:1] withRowAnimation:UITableViewRowAnimationNone];

textFieldDidBeginEditing期间,我使用以下方法保存正在编辑的textField的indexPath:

EditableCustomCell *textFieldCell = (EditableCustomCell *)[[textField superview] superview];
NSIndexPath *indexPath = [MyTableView indexPathForCell:(EditableCustomCell *)textFieldCell];
responderIndexPath = [NSIndexPath indexPathForRow:indexPath.row inSection:indexPath.section];

然后我使用以下代码将正确的行textField设置为第一个响应者:

EditableCustomCell *customCell = (EditableCustomCell *)[MyTableView cellForRowAtIndexPath:responderIndexPath];
[customCell.editableTextField becomeFirstResponder];

一切似乎都很好,直到接近处理结束时,突然textFieldDidBeginEditing开始返回indexPath的第0行0行(即使在检查标记值或包含的文本时返回正确的值文本域)

以下是上述过程开始时的日志:

- textFieldDidEndEditing started  <-- start of delete processing
- textFieldDidEndEditing - tableviewData - replacing object at index 1
    CustomTableViewController.deleteRow - delete called for indexPath section 1 ... row 1
- reloading MyTableView
- CustomTableViewController-cellForRowAtIndexPath started
    CustomTableViewController-cellForRowAtIndexPath section=1 row=0
    CustomTableViewController-cellForRowAtIndexPath ending
    CustomTableViewController-cellForRowAtIndexPath section=1 row=1
    CustomTableViewController-cellForRowAtIndexPath ending
    CustomTableViewController-cellForRowAtIndexPath section=1 row=2
    CustomTableViewController-cellForRowAtIndexPath ending
- textFieldShouldBeginEditing started
    indexPath for textFieldShouldBeginEditing is : section 1 row 1
- textFieldShouldBeginEditing ending
- textFieldDidBeginEditing started
    indexPath for textFieldDidBeginEditing is : section 1 row 1 text 3 tag 1
- textFieldDidBeginEditing ending
- textFieldDidEndEditing ending  <-- end of delete processing
- textFieldDidBeginEditing started
- textFieldDidBeginEditing ... setting responderIndexPath section 0 row 0
    indexPath for textFieldDidBeginEditing is : section 0 row 0 text 123 tag 0
- textFieldDidBeginEditing ending

从日志的最后一部分可以看出,在textFieldDidEndEditing完成后,调用了textFieldDidBeginEditing但返回了第0部分和第0行(这些行始终显示并可见)

我既不明白为什么调用它,也不知道它为什么没有返回正确的indexPath。可以看出,为值返回了文本(在这种情况下输入的值为123),我已经使用其他数据和其他行验证了这一点(对于文本字段的文本和标记)

也许我becomeFirstReponsder textFieldDidEndEditing内的becomeFirstReponder设置不正确,但如果这是真的,我会在哪里处理这个

希望有人能够更好地理解这一点可以帮助我,正如你所知,我已经经历了几个小时而没有任何解决方案

由于 的Izzy

编辑1: 在代码中,textFieldDidEndEditing完成之前调用的所有内容都是cellForRowAtIndexPath。当您在textfieldSHOULDbeginEditing完成后查看日志时,它会输入并存在文本字段TWICE,一次用于刚删除的行下面的行,然后再返回为indexPath的section / row返回0 ?我无法理解导致此post表重新加载方法

的事件序列

编辑2: 只是我,或者在日志末尾的textFieldDidBeginEditing之前没有textFieldDidEndEditing似乎很奇怪?是不是我在{{1}}期间重新加载表格而搞砸了内部流程?有没有更好的地方(即删除一行并重新加载tableview以显示UI更新)?

1 个答案:

答案 0 :(得分:5)

好的,回答我自己的问题......

经过大量调试后,似乎......

通过在textfieldDidEndEditing 期间重新加载表格视图,与标准用户界面工作流程进行互动

调用reloaddata会破坏tableview单元格(以及单元格中包含的所有对象,即UITextFields,UILabels等)并重新创建它们,从而导致

通过将此调用移到一个独立按钮,它按预期运行,而indexPath没有返回0(当它到达这一点时,我仍然不完全理解调用堆栈,但是嘿)

现在我的大问题是决定何时以编程方式调用重新加载,因为我希望它离开文本字段的事件...我感觉到另一个问题:\

希望我的ramblings能帮助将来试图做同样事情的人...