ios UITableView reloadData 自动调用 resignFirstResponder
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6409370/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
UITableView reloadData automatically calls resignFirstResponder
提问by Morpheu5
I have this UITableView with custom cells that can get only predefined values, therefore I use a UIPickerView as their inputView. All is jolly good until I edit a field and need to show its updated value.
我有这个带有自定义单元格的 UITableView,它只能获取预定义的值,因此我使用 UIPickerView 作为它们的 inputView。在我编辑一个字段并需要显示其更新值之前,一切都很好。
In order to make things clearer and easier to maintain, I made delegates and data sources as separate classes, and use notifications to make them interact with the tableView. So, after a value has been chosen from the UIPickerView, the tableView's data source gets notified, and in turn notifies the main ViewController that holds a reference to the tableView. From there I call
为了让事情更清晰、更易于维护,我将委托和数据源作为单独的类,并使用通知使它们与 tableView 交互。因此,从 UIPickerView 中选择一个值后,tableView 的数据源会收到通知,然后通知主 ViewController 持有对 tableView 的引用。从那里我打电话
[_tableView reloadData];
and everything seems to work, except that the UIPickerView disappears, I think because the cells are regenerated and somewhere some resignFirstResponder is called, or something like that. Is there any other way to make the tableView updating its values without having to implement a custom method somewhere that does it, which would be quite ugly?
一切似乎都有效,除了 UIPickerView 消失了,我认为是因为细胞被重新生成,并且在某个地方调用了一些 resignFirstResponder,或者类似的东西。有没有其他方法可以让 tableView 更新其值而不必在某处实现自定义方法,这会很丑陋?
采纳答案by Eiko
This reads like expected behavior - the picker belongs to a particular cell, that cell gets reloaded and is not the first responder any more. I guessone had to select a specific element anyway for the picker to appear, i.e. to make it first responder.
这读起来像预期的行为 - 选择器属于特定单元格,该单元格被重新加载并且不再是第一响应者。我想无论如何都必须选择一个特定的元素才能出现选择器,即使其成为第一响应者。
So you either need to make it become first responder again after reloading, or update the specific cell directly.
因此,您要么需要在重新加载后再次使其成为第一响应者,要么直接更新特定单元格。
回答by valvoline
adding:
添加:
[yourSearchBar becomeFirstResponder];
after your:
在您之后:
[_tableView reloadData];
did the trick
成功了
回答by zutroi
I met the same problem, none of the answers above worked perfectly (I see the keyboard bouncing up and down, etc.).
Following this SO postI fixed the issue by calling
我遇到了同样的问题,上面的答案都不是完美的(我看到键盘上下弹跳等)。
在这篇 SO post 之后,我通过调用解决了这个问题
[tableView beginUpdates];
[tableView endUpdates];
this worked for me, table rows get updates and even expand/shrink (if you are changing rows height dynamically) with a nice animation, all without resigning first responder or even starting keyboard dismiss.
This will not scroll your table view to fit any expanded row, so I put the snippet above in dedicated method, f.e.:
这对我有用,表格行得到更新,甚至扩展/收缩(如果你正在动态改变行高)有一个漂亮的动画,所有这些都没有辞职第一响应者甚至开始键盘关闭。
这不会滚动您的表格视图以适应任何展开的行,因此我将上面的代码段放在专用方法中,fe:
- (void)tableView:(UITableView *)tableView reloadRowWhileShowingKeyboard:(NSIndexPath *)indexPath
{
[tableView beginUpdates];
[tableView endUpdates];
[tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionTop animated:YES];
}
回答by Joris Weimar
I solved this by subclassing UITextView, overriding -(BOOL)resignFirstResponder and by adding a BOOL canResign. this variable is set before reloading the data and unset a short time after.
我通过继承 UITextView、覆盖 -(BOOL)resignFirstResponder 并添加一个 BOOL canResign 来解决这个问题。此变量在重新加载数据之前设置并在短时间内取消设置。
回答by Carlos Ricardo
You can follow this approach, not the best, but it works:
您可以遵循这种方法,这不是最好的方法,但它有效:
// 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];
});
回答by Jonny
I put my UISearchBar in its own section in a UITableView. When firing off the search, I made sure to only refresh the sections which do not contain the search bar.
我把我的 UISearchBar 放在 UITableView 中它自己的部分。在启动搜索时,我确保只刷新不包含搜索栏的部分。
- (void)reloadSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation
回答by Prcela
customTextField.canResign = NO;
[self.tableView reloadData];
customTextField.canResign = YES;
Custom text field is derived from UITextField.
自定义文本字段派生自 UITextField。
.h
。H
@interface CustomTextField : UITextField
@property (nonatomic,assign) BOOL canResign;
@end
.m
.m
- (BOOL)canResignFirstResponder
{
return self.canResign;
}
Make sure that your custom text field is not recreatedon table view reloading.
确保您的自定义文本字段不会在重新加载表视图时重新创建。
回答by Hanton
As mentioned by @Eiko, this works for me!
正如@Eiko 所提到的,这对我有用!
Update the cell in UIPickerViewDelegate's pickerView:didSelectRow:inComponent:
method:
更新 UIPickerViewDelegatepickerView:didSelectRow:inComponent:
方法中的单元格:
- (void) pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
TableViewCell *cell = (TableViewCell *)[self.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:pickerView.tag inSection:0]];
/*
Update your cell here.
*/
// Reload TableViewCell will resign the PickerView, so we need to focus it back.
[self.tableView reloadData];
NSIndexPath* indexPath = [self.tableView indexPathForCell:cell];
NSArray* indexArray = [NSArray arrayWithObjects:indexPath, nil];
[self.tableView reloadRowsAtIndexPaths:indexArray withRowAnimation:UITableViewRowAnimationNone];
[cell.textField becomeFirstResponder];
}
回答by Abhishek Kashyap
Swift solution:
迅捷解决方案:
we can override default canResignFirstResponder by subclassing UITextfiled
我们可以通过继承 UITextfiled 来覆盖默认的 canResignFirstResponder
class CustomField: UITextField{
var canResign:Bool = false
override var canResignFirstResponder: Bool{
return canResign
}
}
all you need to set canResign variable before and after reload statement.
所有你需要在 reload 语句之前和之后设置 canResign 变量。
cell.offerInputTextField.canResign = false
tableView.reloadData()
cell.offerInputTextField.canResign = true
don't forget to assign the custom class text field as CustomField.
不要忘记将自定义类文本字段分配为 CustomField。
回答by Hitesh Agarwal
Track which cell's keyboard is active and then get that particular cell by cellForRowAtIndexPath
and make textView firstResponder
跟踪哪个单元格的键盘处于活动状态,然后获取该特定单元格cellForRowAtIndexPath
并使 textView firstResponder
self.tableView.reloadData()
if let indexPath = self.activeIndexPath{
if let cell = createFormTableView.cellForRow(at: indexPath) as? TextViewTableViewCell {
cell.txtViewInput.becomeFirstResponder()
}
}