具有canBecomeFirstResponder的自定义UITableViewCell在屏幕外时不会取消选择

时间:2013-02-18 11:41:36

标签: ios cocoa-touch uitableview

我最近在UITableView中发现了一些有关选择和取消选择功能的有趣错误。 (是的,这不是一个bug本身,但我发现这种情况非常异常)。

Prehistory:我试图创建一些自定义的TableViewCell类,它可以使用UIDatePicker来选择一些日期并将其放在单元格的标签中。 "CellDate" sample对我来说不是很好。所以我试图将一些自定义inputView设置为单元格并使其成为第一响应者。经过一段时间的研究后,我找到了覆盖自定义UITableViewCell子类的readonly inputView属性的方法,现在它完美地工作:当选择单元格时,我在其上调用[self becomeFirstResponder],当取消选择单元格时,我调用{{ 1}}所以它工作正常,但有一些错误。

当我在屏幕上显示自定义单元格(即不在屏幕外滚动)时,一切都正确,但如果我选择它

Selecting custom cell

滚动tableView向下,这样我的单元格不再在屏幕上

Scrolled down, custom cells are no longer on screen

然后选择另一个单元格

Selecting some other cell while custom cell is no longer on screen

我的自定义单元格不会被取消选择

Unexcpected result

默认UITableViewCell功能的唯一主要变化是:

[self resignFirstResponder]

仅使用此方法覆盖会出现此错误:当前选定的自定义单元格在屏幕外时,它不会因某种原因而取消选择。

我的问题是:有没有人经历过这样的事情,有什么我可以做的吗?因为除此之外,我对日期单元的问题有一个完美的解决方案。

这不是使用UITableViewCells的正确方法吗?我做错了什么吗?我刚刚开始学习iOS,所以我可能不太熟悉其中的一些方面。

P.S。抱歉我的语言不好,我不是母语为英语的人。

更新:

我发现了更多细节。经过一些研究我发现,当你滚动你的tableView并在屏幕外隐藏一些tableViewCell时,它的(单元格)正在被破坏。当你向后滚动时,它会通过调用tableView的委托的tableView:cellForRowAtIndexPath再次创建: 除此之外,如果您尝试为行的indexPath调用[tableView cellForRowAtIndexPath:indexPath],那就是在屏幕外,tableView将返回一个零。

但奇怪的是:当你的自定义单元格是firstResponder时,显然,它不会通过tableView的委托的tableView:cellForRowAtIndexPath:重新创建它,也不会通过[tableView cellForRowAtIndexPath:indexPath]访问它。

至于我,这很奇怪。

2 个答案:

答案 0 :(得分:0)

要直接回答这个问题,UITableView不会取消选择它自己的单元格。在TableView的控制器中,您需要覆盖-(void)tableView:(UITableView *)tableView didselectRowAtIndexPath:(NSIndexPath *)indexPath并手动取消选择所选单元格。

-(void)tableView:(UITableView *)tableView didselectRowAtIndexPath:(NSIndexPath *)indexPath
{
    [tableView deselectRowAtIndexPath:indexPath animate:YES];
}

(为编辑道歉,我在回答时意外保存了)

在UITableViewCell的子类中,您应该覆盖-(void)setEditing:(BOOL)editing animated:(BOOL)animated,以便将单元格转换为可编辑状态。 (将您的UITextField设置为可编辑),然后在您的单元格中,您将使您的文本框成为/退出第一响应者。

当某些内容可编辑时,第一个响应者用来成为响应键盘的下一个对象。

例如,如果您有单元格c1和单元格c2。 c1和c2都包含UITextFields。你在c1,你希望键盘上的Return按钮将文本光标移动到c2,然后当c1需要让UITextField作为第一个响应者辞职,并告诉c2使它的UITextField成为第一个响应者。 你可以通过使自定义单元格成为它的UITextField的委托来实现这一点,然后实现-(BOOL)textFieldShouldReturn:(UITextField *)textField让textField作为第一响应者辞职,然后你会告诉你的UITableView控制器告诉下一个单元格使它的文本字段成为第一个响应者。

答案 1 :(得分:0)

我自己找到了解决方案。它似乎就像在选择其他行时辞职第一响应者一样简单。顺便说一下,我用this answer来完成这个。

希望它可以帮助某人。