我有这个带有自定义单元格的UITableView,它只能获得预定义的值,因此我使用UIPickerView作为它们的inputView。在我编辑一个字段并需要显示其更新值之前,一切都很快乐。
为了使事情更清晰,更容易维护,我将委托和数据源作为单独的类,并使用通知使它们与tableView交互。因此,在从UIPickerView中选择一个值之后,tableView的数据源会得到通知,然后通知主ViewController,它包含对tableView的引用。从那里我打电话
[_tableView reloadData];
并且一切似乎都有效,除了UIPickerView消失之外,我认为因为细胞被重新生成并且在某处调用了一些resignFirstResponder,或类似的东西。 有没有其他方法可以使tableView更新其值而无需在某个地方实现自定义方法,这会非常难看?
答案 0 :(得分:25)
这就像预期的行为一样 - 选择器属于特定的单元格,该单元格被重新加载并且不再是第一个响应者。我猜无论如何必须选择一个特定元素才能让选择器出现,即使其成为第一响应者。
因此,您需要在重新加载后再次成为第一响应者,或直接更新特定单元格。
答案 1 :(得分:22)
中加入:
[yourSearchBar becomeFirstResponder];
之后:
[_tableView reloadData];
做了这个伎俩
答案 2 :(得分:12)
我遇到了同样的问题,上面的答案都没有完美(我看到键盘上下弹跳等)。
在this SO post之后,我通过调用
[tableView beginUpdates];
[tableView endUpdates];
这对我有用,表行获得更新,甚至扩展/缩小(如果你动态地改变行高)动画很好,所有这些都没有让第一响应者退出,甚至没有开始键盘解除。
这不会滚动您的表格视图以适应任何展开的行,因此我将上面的代码段放在专用方法中,例如:
- (void)tableView:(UITableView *)tableView reloadRowWhileShowingKeyboard:(NSIndexPath *)indexPath
{
[tableView beginUpdates];
[tableView endUpdates];
[tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionTop animated:YES];
}
答案 3 :(得分:7)
我通过继承UITextView,重写 - (BOOL)resignFirstResponder并添加BOOL canResign解决了这个问题。此变量在重新加载数据之前设置,并在之后的短时间内取消设置。
答案 4 :(得分: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];
});
答案 5 :(得分:3)
我将UISearchBar放在UITableView的自己的部分中。在启动搜索时,我确保只刷新不包含搜索栏的部分。
img
答案 6 :(得分:1)
customTextField.canResign = NO;
[self.tableView reloadData];
customTextField.canResign = YES;
自定义文本字段派生自UITextField。
.h
@interface CustomTextField : UITextField
@property (nonatomic,assign) BOOL canResign;
@end
<强>的.m 强>
- (BOOL)canResignFirstResponder
{
return self.canResign;
}
确保在重新加载表格视图时,您的自定义文字字段未重新创建。
答案 7 :(得分:0)
如果您在搜索栏中遇到此问题,以下是在iOS 6中为我做的:
答案 8 :(得分:0)
正如@Eiko所说,这对我有用!
使用UIPickerViewDelegate&#39; pickerView: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];
}
答案 9 :(得分:0)
快速解决方案:
我们可以通过继承UITextfiled来覆盖默认的canResignFirstResponder
class CustomField: UITextField{
var canResign:Bool = false
override var canResignFirstResponder: Bool{
return canResign
}
}
你需要在reload语句之前和之后设置canResign变量。
cell.offerInputTextField.canResign = false
tableView.reloadData()
cell.offerInputTextField.canResign = true
不要忘记将自定义类文本字段指定为CustomField。
答案 10 :(得分:0)
跟踪哪个单元格的键盘处于活动状态,然后通过cellForRowAtIndexPath
获取该特定单元格,并使其成为textView firstResponder
self.tableView.reloadData()
if let indexPath = self.activeIndexPath{
if let cell = createFormTableView.cellForRow(at: indexPath) as? TextViewTableViewCell {
cell.txtViewInput.becomeFirstResponder()
}
}
答案 11 :(得分:0)
我使用 beginUpdate 和 endUpdate 结束更新后,获取包含已具有焦点的文本字段的单元格,然后使其成为第一响应者
self.tableView.beginUpdates()
self.tableView.reloadRows(at: [indexPath], with: .automatic)
self.tableView.endUpdates()
let newCell = self.tableView.cellForRow(at: indexPath)
newCell.textField.becomeFirstResponder()
答案 12 :(得分:-1)
您可以通过暂时将第一响应者状态转移到其他对象来解决此问题。通常,您将输入视图的控件传输到ViewController。由于您的UIViewController也继承自UIResponder,您可以执行以下操作:
on didSelect { ....
[yourViewController成为FirstRespoder];
[_ tableView reloadData];
[yourInputField becomeFirstResponder];
.... }
因此,一旦重新加载表格,您就可以将firstResponder状态转回标签/字段。 默认情况下,canBecomeFirstResponder设置为NO。因此,您可能需要在ViewController中覆盖相同的内容。此外,您可能需要使视图控制器的inputView与UIPicker相同,否则它可能会解除您的选择器并显示键盘。