UITableView reloadData自动调用resignFirstResponder

Mor*_*eu5 42 uitableview ios resignfirstresponder

我有这个UITableView与自定义单元格,只能获得预定义的值,因此我使用UIPickerView作为他们的inputView.在我编辑一个字段并需要显示其更新值之前,一切都很快乐.

为了使事情更清晰,更容易维护,我将委托和数据源作为单独的类,并使用通知使它们与tableView交互.因此,在从UIPickerView中选择一个值之后,tableView的数据源会得到通知,然后通知主ViewController,它包含对tableView的引用.从那里我打电话

[_tableView reloadData];
Run Code Online (Sandbox Code Playgroud)

一切似乎都有效,除了UIPickerView消失了,我认为因为细胞被重新生成,某些地方调用了一些resignFirstResponder,或类似的东西.是否有任何其他方法可以使tableView更新其值而无需在某个地方实现自定义方法,这会非常难看?

Eik*_*iko 25

这类似于预期的行为 - 选择器属于特定的单元格,该单元格被重新加载并且不再是第一个响应者.我无论如何必须选择一个特定元素才能让选择器出现,即使其成为第一响应者.

因此,您需要在重新加载后再次成为第一响应者,或直接更新特定单元格.

  • 你是怎么做到的 ? (4认同)

val*_*ine 22

添加:

[yourSearchBar becomeFirstResponder];
Run Code Online (Sandbox Code Playgroud)

在你之后:

[_tableView reloadData];
Run Code Online (Sandbox Code Playgroud)

做了伎俩

  • 这在iOS 5中适用于我.但是在iOS 6中它不起作用.调用[_tableView reloadData]后,数据不会立即重新加载,但是从方法返回后.我不得不重做我的代码以使用UITableView insertXXX,reloadXXX和removeXXX方法,而不是重新加载所有数据.如果您了解iOS 6兼容方法,请分享. (9认同)

小智 15

我遇到了同样的问题,上面的答案都没有完美(我看到键盘上下弹跳等).
这篇SO帖子后,我通过调用解决了这个问题

[tableView beginUpdates];
[tableView endUpdates]; 
Run Code Online (Sandbox Code Playgroud)

这对我有用,表行得到更新,甚至扩展/收缩(如果你动态地改变行高)动画很漂亮,所有这些都没有让第一响应者退出,甚至没有开始键盘解除.
这不会滚动您的表格视图以适合任何展开的行,所以我将上面的代码段放在专用方法中,fe:

- (void)tableView:(UITableView *)tableView reloadRowWhileShowingKeyboard:(NSIndexPath *)indexPath 
{  
    [tableView beginUpdates];
    [tableView endUpdates]; 

    [tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionTop animated:YES];
}
Run Code Online (Sandbox Code Playgroud)

  • 这仅在您不更改行数时才有效. (4认同)

Jor*_*mar 7

我通过继承UITextView,重写 - (BOOL)resignFirstResponder并添加BOOL canResign来解决这个问题.此变量在重新加载数据之前设置,并在之后的短时间内取消设置.

  • 那么你可能没有正确实现它.这对我来说可以. (2认同)

Car*_*rdo 6

您可以遵循这种方法,而不是最好的方法,但它的工作原理:

// pass the responder to a temporary (hidden) textField
[_tmpTextField becomeFirstResponder];

// reload data
[_tableView reloadData];

// reloadData is definitely async... 
// so pass the responder back in a timed op
double delayInSeconds = 0.1;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
    [_textField becomeFirstResponder];
});
Run Code Online (Sandbox Code Playgroud)

  • 我试过这个.他们的键盘似乎非常短暂地解散,然后立即重新出现.也许我没有正确地制作我的`_tmpTextField`.我只是用`[[UITextInput alloc] init]`创建一个,然后将其设置为第一个响应者.鉴于我在UITableViewController实例中,我无法想到还有什么地方可以放置它.救命? (2认同)
  • 它非常有趣,对我有用!!如果将 `delayInSeconds` 设置为 0.1,键盘会显示得更快,但如果设置为 0.001,它就可以工作了!也许,它会导致一些性能问题......我不知道。 (2认同)