快速消息应用程序,uitableview 无法正确响应键盘?
Posted
技术标签:
【中文标题】快速消息应用程序,uitableview 无法正确响应键盘?【英文标题】:swift messaging app, uitableview not responding correctly to keyboard? 【发布时间】:2018-03-22 15:07:22 【问题描述】:一个类似的问题是this,除了我没有估计的行高,我将实际高度存储到字典中,然后使用它们,或者使用UITableViewAutomaticDimension
。
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath)
cellHeightDict[indexPath.row] = cell.frame.size.height
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat
if let height = cellHeightDict[indexPath.row]
return height
else
return UITableViewAutomaticDimension
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat
if let height = cellHeightDict[indexPath.row]
return height
else
return UITableViewAutomaticDimension
所以我现在正在用 Swift 4 制作一个消息传递应用程序。当用户显示键盘时,我希望消息随着键盘向上移动。所以为了做到这一点,我有一个变量keyboardHeight
,它正确得到了键盘的高度:
let keyboardHeight: CGFloat = ((userInfo[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue.height)!
我将表格视图的高度更改为keyboardHeight
:
self.messageTableViewHeight.constant -= keyboardHeight
因此用户可以看到所有的消息。为了通过键盘动画上移消息,我更改了 table view 的 contentOffset:
self.messageTableView.contentOffset.y += keyboardHeight
所有这些都在UIView.animationWithDuration
中,之后我调用self.view.layoutIfNeeded()
,因此转换和一切正常。 但是,当我发送消息时没有滚动到底部,messageTableView 的内容会向下跳??? 而且它似乎向下移动了keyboardHeight
,至少当我看着它。我正在使用messageTableView.reloadData()
。这是一些图片。
Before message sent
它在“Hi”和“Testing”消息之间跳跃。
After message sent
【问题讨论】:
对于文本输入位于最底部的聊天应用程序,通常您只需将视图控制器的整个视图向上移动键盘高度即可 我试过这样做,但是我如何让用户看到所有的消息?如果我将整个表格视图向上移动,那么它会在标题下方滑动。 我想把它向上移动,然后调整 contentInset,但是滚动条会滚动到视图之外,插入行也是一个问题。 【参考方案1】:只要你重新加载 tableview messageTableView.reloadData()
的数据。每行都会重新加载,但它无法以某种方式计算实际的内容大小。您可以尝试重新加载主队列中的数据。
DispatchQueue.main.async
messageTableView.reloadData()
如果仍然无法正常工作,您可以在上面的代码中再添加一件事。假设您的班级中有一组消息。 var messages
那么你就可以使用这段代码在tableview中正确显示数据了。
DispatchQueue.main.async
messageTableView.reloadData()
if messages.count > 0
let indexPath = IndexPath(row: messages.count - 1, section: 0)
self.messageTableView.scrollToItem(at: indexPath, at: .bottom, animated: true)
希望这会有所帮助。编码愉快。
【讨论】:
基本上每次 ui 更新都应该在主线程上完成,在重新加载数据后,我们只是将 tableview 滚动到最后一个单元格的底部位置。 所以当我更新约束或使用 UIView.animate 时,我应该使用 DispatchQueue.main.async 吗?抱歉,我还是个初学者。 在动画的情况下,一旦你通过了块,它就会立即被调用,所以你不需要把它们放在任何队列中。操作系统通常会自行处理所有动画。但这里有个问题,假设您正在后台线程中执行某些操作,并且您需要使用动画更新 UI,那么您必须返回主队列来执行动画。这完全取决于您的代码是如何执行的。以上是关于快速消息应用程序,uitableview 无法正确响应键盘?的主要内容,如果未能解决你的问题,请参考以下文章
带有 UITableView 的 UITabBar - 我可以正确看到表格,但无法选择一行
如果无法从 Firebase 实时数据库中检索数据,则尝试在 UITableView 上显示消息