在 UITableViewController 上编辑 UITextField 时滚动区域不正确

Posted

技术标签:

【中文标题】在 UITableViewController 上编辑 UITextField 时滚动区域不正确【英文标题】:Scroll area incorrect when editing UITextField on UITableViewController 【发布时间】:2014-02-26 19:31:32 【问题描述】:

我有一个UITableViewController 的分组样式,在 iPhone 上。我现在在 ios 7.0.6 上。在我的一些单元格上是UITextField's。编辑文本字段时,滚动区域自动调整;我没有添加代码来做到这一点。我唯一拥有的与滚动相关的东西是:

[self.tableView scrollToRowAtIndexPath:nameIndexPath
                      atScrollPosition:UITableViewScrollPositionNone
                              animated:YES];

但我只在textField:shouldChangeCharactersInRange:replacementString: 中调用它,所以当我点击文本字段时甚至不会调用它。

我的问题是,在键盘可见的情况下,我可以将表格内容向上滚动太多。似乎恰好是标签栏高度太远了;我的应用是基于标签栏的。在下图中,您可以看到滚动条在键盘上方停止了一个标签栏高度。 (不重要的说明:文本字段一直向上滚动,所以你看不到它。)

看起来像另一个 iOS 7 错误。任何想法我可以如何解决这个问题,因为它看起来相当草率。

注意:在其他情况下,我在 iOS 上也看到过类似的插入问题。我想很快就会修复(至少我希望如此;因为这些是一个非常简单的 iOS 错误)。

【问题讨论】:

【参考方案1】:

原来contentInsetscrollIndicatorInsets 都不正确:(64, 0, **265**, 0)。底部插入值为 55 磅(即标签栏高度)。

正确的底部插图当然必须是键盘高度216

在 Apple 齐心协力之前解决这个问题:

- (BOOL)textFieldShouldBeginEditing:(UITextField*)textField

    dispatch_time_t when = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.6 * NSEC_PER_SEC));
    dispatch_after(when, dispatch_get_main_queue(), ^(void)
    
        // Must be delayed until after iOS has adjusted the insets,
        // which turns out to be 'way before' the keyboard animation has finished.
        [self.tableView setContentInset:UIEdgeInsetsMake(64, 0, 216, 0)];
        [self.tableView setScrollIndicatorInsets:UIEdgeInsetsMake(64, 0, 216, 0)];
    );

    return YES;

和:

- (BOOL)textFieldShouldReturn:(UITextField*)textField

    [textField resignFirstResponder];

    // iOS seems to set the insets differential: So we must set them back
    // to the incorrect values for iOS to subtract the bottom inset back
    // to 55 again.
    // No delay needed here of course because we must do this before the
    // keyboard animation starts.
    [self.tableView setContentInset:UIEdgeInsetsMake(64, 0, 265, 0)];
    [self.tableView setScrollIndicatorInsets:UIEdgeInsetsMake(64, 0, 265, 0)];

    return YES;

编辑:为确保此解决方法能够抵抗 Apple 修复,让我们这样做:

dispatch_time_t when = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.6 * NSEC_PER_SEC));
dispatch_after(when, dispatch_get_main_queue(), ^(void)

    if (self.tableView.contentInset.bottom == 265)
    
        [self.tableView setContentInset:UIEdgeInsetsMake(64, 0, 216, 0)];
        [self.tableView setScrollIndicatorInsets:UIEdgeInsetsMake(64, 0, 216, 0)];
    
);

【讨论】:

以上是关于在 UITableViewController 上编辑 UITextField 时滚动区域不正确的主要内容,如果未能解决你的问题,请参考以下文章

NSLayoutContraints 在 UITableViewController 上应用不一致(显然)

在后退导航上更新 UITableViewController

如何在当前UITableViewController上添加UIView

如何将 UITableViewController 创建为可重用模块?

iOS 15 上 UITableViewController 的便捷初始化崩溃

在 UITableViewController 的 refreshControl 上缓慢向下滑动刷新会导致视图跳下