UITextField 成为第一响应者后,UITableView 不会将单元格滚动到可见

Posted

技术标签:

【中文标题】UITextField 成为第一响应者后,UITableView 不会将单元格滚动到可见【英文标题】:UITableView does not scroll cell to visible after UITextField becomes first responder 【发布时间】:2013-06-21 09:40:42 【问题描述】:

我有一个装有自定义单元格的UITableView。这些单元格有两种可能的状态:只读状态和编辑状态。我通过点击表格视图中的相应行在它们之间进行更改:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath

    CustomClass *aCustomClass = [self.model objectAtIndex:indexPath.row];
    [aCustomClass setEdition:YES];

    [tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];

问题是我需要在点击该行后将单元格的UITextField 设置为第一响应者。我所做的是添加以下代码:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

    cell = [tableView dequeueReusableCellWithIdentifier:@"MyCell"];

    if (!cell)
        cell = ... // Create cell

    ...

    [cell.textField becomeFirstResponder];

一切正常,但是当UITextField 成为第一响应者时,我希望表格视图将整个单元格滚动到可见。为此,我实现了一个键盘通知事件,如下所示:

- (void)keyboardWillBeShown:(NSNotification*)aNotification

    NSDictionary* info = [aNotification userInfo];
    CGRect kbRawRect = [[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
    CGRect ownFrame = [self.tableView.window convertRect:self.tableView.frame fromView:self.tableView.superview];

    // Calculate the area that is covered by the keyboard
    CGRect coveredFrame = CGRectIntersection(ownFrame, kbRawRect);

    coveredFrame = [self.tableView.window convertRect:coveredFrame toView:self.tableView.superview];

    UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0, coveredFrame.size.height, 0.0);
    self.tableView.contentInset = contentInsets;
    self.tableView.scrollIndicatorInsets = contentInsets;

    [self.tableView scrollToRowAtIndexPath:self.openCellIndexPath atScrollPosition:UITableViewScrollPositionTop animated:YES];

问题是,表格视图不会将单元格滚动到顶部位置,如最后一行所示。

如果我删除自动becomeFirstResponder 呼叫并手动点击UITextField,一切正常。

您知道为什么会发生这种情况吗?我该如何解决这个问题?

谢谢,

【问题讨论】:

为什么不添加 [cell.textField becomeFirstResponder];在 didselectrowAtIndexPath 中而不是在 cellForRowAtIndexPath 中。 它不工作。当我希望整个单元格可见时,只有文本字段可见。谢谢。 您不能将 TextField 和整个单元格之间的差异(以像素为单位)添加到计算中,以便整个单元格可见吗? 我不能。 scrollToRowAtIndexPath: 根本不工作。如果我自己点击文本字段,那么它就可以工作了。 先在 textField 上尝试 resignFirstResponder,然后再应用 ScrollToRowAtIndexPath,看看是否有效。 【参考方案1】:
UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0, coveredFrame.size.height, 0.0);

应该这样改变:

UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0, -coveredFrame.size.height, 0.0);

【讨论】:

可能想详细说明原因以及上述解决方法。

以上是关于UITextField 成为第一响应者后,UITableView 不会将单元格滚动到可见的主要内容,如果未能解决你的问题,请参考以下文章

在 tableView 中插入新行后保存成为第一响应者的 UITextField 文本

UITextField 不能成为 UITableView 中的第一响应者

UITextField 没有成为集合视图中的第一响应者

为啥 uitextfield 在成为第一响应者时从不返回 nil?

当 UITextField 成为第一响应者时禁用 UIScrollView 滚动

UITableView 中的 UITextField 没有成为第一响应者