尝试删除包含拒绝辞职的第一响应者的行

时间:2012-12-17 01:44:12

标签: ios uitableview uitextfield first-responder

我有一个基于iOS 6的项目,它实现了UITableView。表视图中的每个单元格都包含UITextField,允许用户输入信息。如果用户清除文本字段,或者删除字段中的所有输入(即[textfield length] == 0),当他们点击另一个单元格(文本字段)时,它会从表格视图中删除前一个单元格(文本字段),因为它是空 - 这可以避免在表视图中累积空单元格。

这一切都是使用名为-textFieldEditingDidEnd:的方法完成的,该方法会针对文本字段的UIControlEventEditingDidEnd事件触发:

- (void)textFieldEditingDidEnd:(UITextField *)textField {

    NSIndexPath *indexPath = // Index path of the row in the table view

    if ([textField.text length] == 0) {
        // Delete the cell from the table view
        [self.tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
    }

}

但是,当代码被触发时,应用程序在控制台上崩溃并显示以下消息:

*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Attempt to delete row containing first responder that refused to resign'

我之前从未见过这个消息,在搜索网页时似乎没有特别多的引用。我很感激有关如何解决这个问题的任何建议。

7 个答案:

答案 0 :(得分:11)

我以前从未见过这个消息,但如果我看到它的话,我的直接冲动是:尝试延迟表现。即使是这样简单的事情也许是一个有趣的实验:

dispatch_async(dispatch_get_main_queue(), ^{
    [self.tableView deleteRowsAtIndexPaths:@[indexPath] 
     withRowAnimation:UITableViewRowAnimationAutomatic];
});

我的想法是,当文本字段仍在报告时(即textFieldEditingDidEnd仍在运行时),我们不要尝试删除该行;让runloop有机会完成它的循环。

答案 1 :(得分:1)

我也遇到了同样的问题。当键盘存在时,您需要先调用resignFirstResponder,然后在

之后调用UITableview重新加载方法
(void)textFieldDidEndEditing:(UITextField *)textField

委托方法执行或内部:

(void)textFieldDidEndEditing:(UITextField *)textField{
    [tableview reloadData];
}

答案 2 :(得分:1)

我的崩溃来自UIWebView内的可编辑UICollectionViewCell。以下修正了它:

[self.view endEditing:YES]

答案 3 :(得分:-1)

我遇到了同样的NSInternalInconsistencyException例外情况。我的解决方案如下:

textView.selectedTextRange = nil;    // clear the selected text
[textView resignFirstResponder];

答案 4 :(得分:-1)

从键盘隐藏UITableViewCell通知中删除包含UITextView的{​​{1}}时出现此错误。

修复是将逻辑移到UIKeyboardWillHideNotification

答案 5 :(得分:-1)

当我的方法textFieldShouldEndEditing在某些情况下返回NO时,我遇到了这个问题

答案 6 :(得分:-1)

我也遇到了同样的问题。即使在调用“resignFirstResponer”和“endEditing”之后,它也会被发现崩溃。

当我尝试使用@ matt的方法时,它运行正常。谢谢亚光。

似乎因为我们将“deleteRowsAtIndexPaths:”添加到GCD队列中,所以队列将确保先前任务在队列中完成,然后仅启动main_queue中的下一个任务。因此无需添加任何延迟。