通用 UITableView 键盘调整大小算法

2023-11-27

我搜索了很多调整表视图大小以适应键盘显示和隐藏的代码,但我遇到的几乎每一篇文章都假设表视图正在获取其视图控制器的整个视图。我有一个 iPad 应用程序,其中表格视图仅占据屏幕的一部分。在这种情况下调整表视图大小的正确方法是什么? (我上面提到的帖子中的所有代码都失败了)


以下代码可以满足您的需求,并且适用于任何设备和任何布局。该代码是由明智的TableView框架(经许可复制和使用)。

- (void)keyboardWillShow:(NSNotification *)aNotification
{
if(keyboardShown) 
    return;

keyboardShown = YES;

// Get the keyboard size
UIScrollView *tableView;
if([self.tableView.superview isKindOfClass:[UIScrollView class]])
    tableView = (UIScrollView *)self.tableView.superview;
else
    tableView = self.tableView;
NSDictionary *userInfo = [aNotification userInfo];
NSValue *aValue = [userInfo objectForKey:UIKeyboardFrameEndUserInfoKey];
CGRect keyboardRect = [tableView.superview convertRect:[aValue CGRectValue] fromView:nil];

// Get the keyboard's animation details
NSTimeInterval animationDuration;
[[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] getValue:&animationDuration];
UIViewAnimationCurve animationCurve;
[[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] getValue:&animationCurve];

// Determine how much overlap exists between tableView and the keyboard
CGRect tableFrame = tableView.frame;
CGFloat tableLowerYCoord = tableFrame.origin.y + tableFrame.size.height;
keyboardOverlap = tableLowerYCoord - keyboardRect.origin.y;
if(self.inputAccessoryView && keyboardOverlap>0)
{
    CGFloat accessoryHeight = self.inputAccessoryView.frame.size.height;
    keyboardOverlap -= accessoryHeight;

    tableView.contentInset = UIEdgeInsetsMake(0, 0, accessoryHeight, 0);
    tableView.scrollIndicatorInsets = UIEdgeInsetsMake(0, 0, accessoryHeight, 0);
}

if(keyboardOverlap < 0)
    keyboardOverlap = 0;

if(keyboardOverlap != 0)
{
    tableFrame.size.height -= keyboardOverlap;

    NSTimeInterval delay = 0;
    if(keyboardRect.size.height)
    {
        delay = (1 - keyboardOverlap/keyboardRect.size.height)*animationDuration;
        animationDuration = animationDuration * keyboardOverlap/keyboardRect.size.height;
    }

    [UIView animateWithDuration:animationDuration delay:delay 
                        options:UIViewAnimationOptionBeginFromCurrentState 
                     animations:^{ tableView.frame = tableFrame; } 
                     completion:^(BOOL finished){ [self tableAnimationEnded:nil finished:nil contextInfo:nil]; }];
}
}

- (void)keyboardWillHide:(NSNotification *)aNotification
{
if(!keyboardShown)
    return;

keyboardShown = NO;

UIScrollView *tableView;
if([self.tableView.superview isKindOfClass:[UIScrollView class]])
    tableView = (UIScrollView *)self.tableView.superview;
else
    tableView = self.tableView;
if(self.inputAccessoryView)
{
    tableView.contentInset = UIEdgeInsetsZero;
    tableView.scrollIndicatorInsets = UIEdgeInsetsZero;
}

if(keyboardOverlap == 0)
    return;

// Get the size & animation details of the keyboard
NSDictionary *userInfo = [aNotification userInfo];
NSValue *aValue = [userInfo objectForKey:UIKeyboardFrameEndUserInfoKey];
CGRect keyboardRect = [tableView.superview convertRect:[aValue CGRectValue] fromView:nil];

NSTimeInterval animationDuration;
[[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] getValue:&animationDuration];
UIViewAnimationCurve animationCurve;
[[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] getValue:&animationCurve];

CGRect tableFrame = tableView.frame; 
tableFrame.size.height += keyboardOverlap;

if(keyboardRect.size.height)
    animationDuration = animationDuration * keyboardOverlap/keyboardRect.size.height;

[UIView animateWithDuration:animationDuration delay:0 
                    options:UIViewAnimationOptionBeginFromCurrentState 
                 animations:^{ tableView.frame = tableFrame; } 
                 completion:nil];
}

- (void) tableAnimationEnded:(NSString*)animationID finished:(NSNumber *)finished contextInfo:(void *)context
{
// Scroll to the active cell
if(self.activeCellIndexPath)
{
    [self.tableView scrollToRowAtIndexPath:self.activeCellIndexPath atScrollPosition:UITableViewScrollPositionNone animated:YES];
    [self.tableView selectRowAtIndexPath:self.activeCellIndexPath animated:NO scrollPosition:UITableViewScrollPositionNone];
}
}

Notes:

A。以上两种方法均已添加到通知中心,代码如下:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];

b.上面使用的 ivars 声明如下:

BOOL keyboardShown;
CGFloat keyboardOverlap;

C。 'self.activeCellIndexPath' 始终设置为拥有当前活动 UITextField/UITextView 的单元格的索引路径。

享受! :)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

通用 UITableView 键盘调整大小算法 的相关文章

随机推荐

  • ObjectListView - 通过单击具有固定内容/文本的指定列来删除行

    我有一个简单的问题 我自己无法解决 我有一个 ObjectListView 其中填充了我的一些对象 但除此之外 我想要另一列 其默认文本为 删除 单击该列后 应删除所选行 我怎么做 您可以通过使所需的行可编辑并使用 CellEditActi
  • 如何在 Keycloak 中执行电子邮件操作

    我尝试使用 Keycloak API 触发发送电子邮件 但没有成功 正如文档中首先描述的 我正在为我的管理员用户获取令牌 curl d client id admin cli d username admin d password admi
  • 对集合进行排序并根据特定标准对结果进行排名

    假设我有以下内容 var searches new ObservableCollection
  • 绘制带有圆周的 3D 球体

    我正在尝试使用 matplotlib 绘制一个像这样的球体 但我找不到一种在背面有虚线的方法 而且垂直周长看起来有点奇怪 import numpy as np import matplotlib pyplot as plt from mpl
  • Spark Dataframe 列与其他列的最后一个字符

    我正在寻找一种方法来从数据帧列中的字符串中获取最后一个字符并将其放入另一列中 我有一个 Spark 数据框 如下所示 animal cat mouse snake 我想要这样的东西 lastchar t e e 现在我可以使用如下 UDF
  • Apache JMeter支持http/2请求吗?

    JMeter 3 2 支持 HTTP2 吗 从版本 4 0 开始 Core JMeter 不支持 HTTP2 但有一个plugin实现它 This plugin可以通过安装JMeter 插件管理器 关于HTTP Client 自2018年1
  • Jquery背景动画

    是否可以将其动画化background color在 jQuery 中 因为它不起作用 something animate background red 1000 来自docs The jQuery用户界面项目扩展了 animate 方法通
  • 使用 Node JS 将记录数组插入 mysql

    我有一组类似的数据 var records Name Id 1 Name Id 2 Name Id 3 Name Id 4 Name Id 5 Name Id 6 记录数组中可能有数千个项目 问题1 我们可以创建一个存储过程来接受mysql
  • 为 Python 2/3 实现 Google 的 DiffMatchPatch API

    我想用 Python 编写一个简单的 diff 应用程序Google 的差异匹配补丁 API 我对 Python 还很陌生 所以我想要一个示例来说明如何使用 Diff Match Patch API 对两个文本段落进行语义比较 我不太确定如
  • Django 注释:想要删除用户 URL,而不是扩展模型。如何?

    我完全理解有关在 Django 中扩展评论应用程序的文档 并且真的想坚持使用自动功能but 在当前的应用程序中 我完全没有必要将 URL 与评论一起提交 Being 微创默认设置 我怎样才能防止这个字段出现在评论表单中 使用 Django
  • 无法使 GWT 应用程序作为 Chrome 打包应用程序工作,可能是由于 CSP

    不断收到 CSP 错误 拒绝执行内联脚本 因为它违反了以下内容安全策略指令 script src self 该问题可能是由于 GWT 生成的 HTML 文件包含内联 JS UPD 更改为清单版本 1 有所帮助 但这是一个临时解决方法 因为
  • Java世界里有类似WPF和MVVM的东西吗?

    Java世界里有类似WPF和MVVM的东西吗 你见过吗eFace eFace 是 Java 中的 XAML WPF 解决方案 第一个版本可用于 现在下载 http www soyatec com eface installation Jav
  • 我可以在 .ld 文件中使用预处理器指令吗

    我可以在 ld 文件中使用预处理器指令吗 我需要使用两组 ld 文件中的一组 并希望让构建引擎使用宏来决定 我可以这样做吗 是的你可以 您需要为链接器脚本手动运行预处理器 如下所示 in your linker script ld out
  • 为什么 Scala 中的柯里化需要多个参数列表?

    假设我有一个有 2 个参数的函数 需要部分应用 我需要将其定义为 def f a Int b Int some code 然后我可以将其部分应用为def fWithA f a 我的问题是 为了柯里化函数 为什么 Scala 要求使用多个参数
  • 相当于Java中C的“_getch()”函数吗?

    我使用 Google Wave 并且我想模拟在您实际按下 Enter 键之前发送消息的功能 Java中是否有相当于C函数的函数 getch 您可以使用 JLine 库的 ConsoleReader readVirtualKey 方法 看ht
  • 当页面重新加载时,JavaScript setTimeout 函数是否停止?

    如果我发起一个setTimeout函数从触发器 当页面重新加载时函数会停止吗 我发起一个setTimeout功能periodic update on the onload我的页面的事件 这是否创建了多个实例periodic update 功
  • C++0x 将不再有概念。意见?这将如何影响你?

    在 2009 年 7 月C 0x 法兰克福会议 决定删除概念来自 C 0x 就我个人而言 我很失望 但我宁愿有一个可实现的 C 0x 也不愿没有 C 0x 他们表示将在稍后添加 您对此决定 问题有何看法 它将如何影响你 就我个人而言 我对删
  • 将文本基线与 div 底部对齐

    我正在尝试调整baseline中的某些文本div到所说的最底部边缘div 这样的角色就像g and j实际上会溢出 div 我似乎只能将文本元素的底部边缘与文本元素的底部边缘对齐div 我尝试过使用vertical align有价值观bas
  • CSS 选择器 * + * 定义?

    css 选择器 到底是什么意思 当您执行检查元素时 您可以在谷歌浏览器的控制台中看到它 根据我的说法 这似乎是对 每个第二个孩子 应用一种风格 但仍然想确定一下 谁能帮我吗 Example margin top 1em 表示 任何具有前一个
  • 通用 UITableView 键盘调整大小算法

    我搜索了很多调整表视图大小以适应键盘显示和隐藏的代码 但我遇到的几乎每一篇文章都假设表视图正在获取其视图控制器的整个视图 我有一个 iPad 应用程序 其中表格视图仅占据屏幕的一部分 在这种情况下调整表视图大小的正确方法是什么 我上面提到的