【发布时间】:2019-02-26 10:58:32
【问题描述】:
我正在开发一个应该在 iOS 11 和 12 上运行的聊天。在 iOS 12 上,一切都按预期运行。但是,在 iOS 11 上,我遇到的问题是,一旦键盘出现,表格视图内容的大小就会增加(没有单元格)。额外高度的数量与键盘高度匹配。
演示
这是一个演示,左侧是 iOS 11,右侧是 iOS 12。在 iOS 12 上一切正常。当键盘出现时,请注意 iOS 11 上 table view 的底部。
视图/视图控制器层次结构设置
- = 视图控制器+ = 视图
- UINavigationViewController
- UIViewController // Controlling contentInsets, contentOffset of the tableView
+ UIView
- UITableViewController
+ UITableView
- UIViewController // Controlling the text input bar at the bottom
+ ... // Other views
+ UITextView
布局约束
表格视图的锚点等于其父视图的锚点。所以全屏,忽略安全区域。因此,当键盘出现时,框架不会改变,但底部的内容会插入。
更多详情
我已经设置tableView.contentInsetAdjustmentBehavior = .never
这是我在键盘出现时计算表格视图的插入和偏移的方式。这很复杂,因为有几种情况应该有不同的行为。当键盘消失以及文本输入的高度发生变化时,也会进行类似的复杂计算。我总是想根据视图框架的变化向上或向下滚动表格视图。
@objc func handleKeyboardWillShowNotification(_ notification: NSNotification) {
let frameEnd: CGRect = (notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as AnyObject).cgRectValue ?? .zero
let keyboardHeight = frameEnd.height
let contentHeight = tableView.contentSize.height
let visibleTableViewHeight = tableView.frame.height - (tableView.contentInset.top + tableView.contentInset.bottom)
let distanceToScroll = (keyboardHeight - view.safeAreaInsets.bottom)
var y: CGFloat = 0
if contentHeight > visibleTableViewHeight {
y = tableView.contentOffset.y + distanceToScroll
} else {
let diff = visibleTableViewHeight - contentHeight
let positionAtKeyboard = distanceToScroll - tableView.contentInset.top - diff
y = positionAtKeyboard < tableView.contentInset.top ? -tableView.contentInset.top : positionAtKeyboard
}
let contentOffset = CGPoint(x: 0, y: y)
tableView.contentInset.bottom = keyboardHeight + inputBar.frame.height
tableView.scrollIndicatorInsets = tableView.contentInset
tableView.setContentOffset(contentOffset, animated: false)
}
我也在不同的屏幕尺寸上试过这个,它总是给contentSize增加一个与键盘高度完全匹配的数量。
【问题讨论】:
-
不确定 iOS 版本对此有何影响,但作为替代方案,您可以使用 UITableViewController 作为主控制器。这内置了对键盘避免滚动的支持,您无需手动执行任何操作。
-
ios 11 及以上版本不要使用 UIResponder.keyboardDidShowNotification 观察者,而是使用 UIResponder.keyboardWillChangeFrameNotification
标签: ios swift uitableview uiscrollview ios11