【问题标题】:Keep Bottom of TableView Visible When Keyboard Shows With Autolayout in Swift当键盘在 Swift 中使用自动布局显示时,保持 UITableView 的底部可见
【发布时间】:2018-10-23 16:39:37
【问题描述】:

我有一个带有文本视图的表格视图,用于在其下方输入文本,类似于 Apple 消息。当用户开始输入文本并出现键盘时,我想要类似于 IOS Messages 的以下行为。

  1. 如果键盘不覆盖任何东西,tableview 的可见部分保持不变。

  2. 如果键盘会覆盖某些东西,则 tableview 会向上移动,使其底部填充的单元格刚好位于键盘上方。

因为我使用的是自动布局,所以我目前在 tableview 和它下面的 textview 之间有一个约束。此外,该项目有 IQKeyboard 管理许多其他涉及文本字段和文本视图的视图。

结合IQKeyboard的约束完成2.当键盘出现时,键盘将textview向上推。 textview 将 tableview 向上推。因此,如果 tableview 已完全填充,您会根据需要在键盘上方的 textview 上方看到 tableview 的最后一个单元格。

但是,2. 不起作用。

如果tableview没有被填满,键盘将textview向上推,textview向上推,这样你就可以看到tableview的顶部了。

我尝试在键盘显示和此类工作时调整 tableview 的 contentOffset 属性,但 tableview 在返回之前最初向上移动。我认为这是因为直到键盘开始向上移动之后才会触发更改偏移属性的通知。

我还尝试将 tableview 高度调整为其内容,但这会导致 textview 扩展以填充由于约束而导致的差异。

Content offset approach - problem is that content offset adjusts too late
//register for keyboard notifications and in handler:
if let infoKey  = notification.userInfo?[UIKeyboardFrameEndUserInfoKey],
   let rawFrame = (infoKey as AnyObject).cgRectValue {
     let keyboardFrame = view.convert(rawFrame, from: nil)
     self.heightKeyboard = keyboardFrame.size.height
     UIView.animate(withDuration: 0.2, animations: {
             self.tableView.contentInset = UIEdgeInsetsMake(self.heightKeyboard!, 0, 0, 0);
     })
}

谁能提出一种模仿 Apple Messages 行为的方法?提前感谢您的任何建议。

【问题讨论】:

  • 而不是 "push up the tableview" 有你的约束 shrink tableview 的大小,并将 tableview 滚动到底部。跨度>
  • 当我缩小 tableview 时,它会缩小,但它下面的 textview 会扩大以填补差异。这是因为 tableview 底部受限于 textview 顶部。
  • 当我改变表格和文本视图之间的约束而不是缩小表格时,也会发生同样的事情。文本视图扩展而不是表格向下移动。我认为这是由于 tableview 被限制在顶部而 textview 被限制在底部。由于 IQKeyboardManager,键盘上下推动整个超级视图,这通常是一个很好的下降。我想我需要修改 tableview 插图,但在不同的地方这样做,所以它发生在键盘出现之前或同时出现。跨度>

标签: ios swift keyboard tableview


【解决方案1】:

一种方法:

  • 将tableView的顶部约束到视图的顶部
  • 将tableView的底部约束到textField的顶部
  • 将 textField 的底部约束到视图的底部
  • 为 textField 的底部约束创建 @IBOutlet

当显示键盘时,将 textField 底部约束的.constant 更改为键盘视图的高度。

这会将 textField 向上移动,并且因为它的顶部被限制在 tableView 的底部,它也会将 tableView 的底部边缘向上移动。

然后滚动到tableView的底部。

布局:

初始层次结构,有 20 行(滚动到底部):

层次结构视图(tableView背景颜色设置为绿色,所以我们可以看到它的框架):

显示键盘后查看:

显示键盘后的层次结构:

从静态屏幕上看不太清楚,但绿色矩形的框架(tableView 背景)现在更短了...用户仍然可以上下滚动查看所有行,但 tableView 的底部仍然被限制在 textField 的顶部。

当您关闭键盘时,将 textField 底部约束的 .constant 设置回零。

您可以在 GitHub 上查看完整的工作示例项目:https://github.com/DonMag/KBAdjust

【讨论】:

  • 感谢您的深入回答。它完全适用于 tableview 完全填充的情况。但是,当 tableview 中只有一个或两个填充单元格时,我希望这些单元格在 keyoard 出现时保持可见,所以我希望 tableview 不移动。我尝试将 tableview 调整为 textview 约束,向下调整 keybaord 高度(大约 -300),但这会炸毁 textview 以填补空白。也许我应该同时将 top ofTableview 增加到 top ofView 约束以同时将 tableview 向下推。会试试这个,让你知道它是否有效。
  • 您的约束不能完全正确。我在 GitHub 上放了一个完整的、可运行的示例项目:github.com/DonMag/KBAdjust ... 请参阅 viewDidLoad() 开头的 cmets,从几行变为很多行。
  • 非常感谢您的帮助。我无法打开您的项目——可能是因为我正在运行 Xcode 8.3,但我复制了您的代码。它确实有效,尽管对我来说上表行消失然后从顶部返回。这与当键盘和文本视图跳起来时 tableview 完全静止的 imessage 不同。但是,它可能与我的其余代码有关,因此将您的答案标记为正确。
猜你喜欢
  • 2018-09-27
  • 2016-09-07
  • 2016-08-06
  • 1970-01-01
  • 2020-03-14
  • 1970-01-01
  • 1970-01-01
  • 2019-06-24
  • 2021-10-14
相关资源
最近更新 更多