[英]UITableView adds height of keyboard to contentSize when the keyboard appears on iOS11
我正在進行一項應該適用於iOS 11和12的聊天。在iOS 12上,一切都按預期工作。 但是,在iOS 11上,我遇到鍵盤出現時表視圖內容大小增加(無單元格)的問題。 額外高度的數量與鍵盤高度相匹配。
這是一個左側是iOS 11,右側是iOS 12的演示。 在iOS 12上一切正常。 當鍵盤出現時,請注意iOS 11上表格視圖的底部。
-
=查看控制器
+
=查看
- UINavigationViewController
- UIViewController // Controlling contentInsets, contentOffset of the tableView
+ UIView
- UITableViewController
+ UITableView
- UIViewController // Controlling the text input bar at the bottom
+ ... // Other views
+ UITextView
表視圖的錨點等於其superview的錨點。 所以全屏,忽略安全區域。 因此,當鍵盤出現時,框架不會改變,但底部內容會插入。
我設置了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
添加一個與鍵盤高度完全匹配的數量。
首先,您不必進行不必要的計算只需計算鍵盤高度,然后將鍵盤向上移動即可。
Swift版本:
@objc func keyboardWillShow(notification: NSNotification) {
if let keyboardSize = (notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue {
self.tableView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: keyboardSize.height + 10, right: 0)
UIView.animate(withDuration: 0.25) {
self.tableView.layoutIfNeeded()
self.view.layoutIfNeeded()
}
}
}
@objc func keyboardWillHide(notification: NSNotification) {
self.tableView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
UIView.animate(withDuration: 0.5) {
self.tableView.layoutIfNeeded()
self.view.layoutIfNeeded()
}
}
Objecttive-C版本:
- (void)keyboardWillShow:(NSNotification *)notification
{
NSDictionary *keyInfo = [notification userInfo];
CGRect keyboardFrame = [[keyInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
self.tableView.contentInset = UIEdgeInsetsMake(0, 0, keyboardFrame.size.height + 10, 0);
[UIView animateWithDuration:0.2 animations:^{
[self.tableView layoutIfNeeded];
[self.view layoutIfNeeded];
} completion:nil];
}
- (void) keyboardWillHide: (NSNotification *) notification
{
self.tableView.contentInset = UIEdgeInsetsMake(0, 0, 0, 0);
[UIView animateWithDuration:0.2 animations:^{
[self.view layoutIfNeeded];
} completion:nil];
}
如果您發現任何困難,請告訴我。 這對我很有用
您可以使用以下代碼進行鍵盤隱藏和顯示。
//顯示鍵盤
@objc func keyboardWillAppear(_ notification: NSNotification) {
if let newFrame = (notification.userInfo?[ UIResponder.keyboardFrameEndUserInfoKey ] as? NSValue)?.cgRectValue {
if self.tableView.contentInset.bottom == 0 {
let insets: UIEdgeInsets = UIEdgeInsets( top: 0, left: 0, bottom: newFrame.height, right: 0 )
self.tableView.contentInset = insets
self.tableView.scrollIndicatorInsets = insets
UIView.animate(withDuration: 0.1) {
self.view.layoutIfNeeded()
}
}
}
}
//隱藏鍵盤
@objc func keyboardWillDisappear(_ notification: NSNotification) {
if self.tableView.contentInset.bottom != 0 {
self.tableView.contentInset = UIEdgeInsets( top: 0, left: 0, bottom: 0, right: 0 )
self.tableView.scrollIndicatorInsets = UIEdgeInsets( top: 0, left: 0, bottom: 0, right: 0 )
UIView.animate(withDuration: 0.1) {
self.view.layoutIfNeeded()
}
}
}
這對我有用。
這不是專門回答原始問題,但可能是那些沒有半透明鍵盤和輸入視圖的人的解決方案。
我可以通過更改約束而不設置底部插入來解決此問題。 最初,表視圖的底部約束設置在超級視圖的底部(基本上是屏幕的底部)。 所以當鍵盤出現時,我沒有改變表格視圖的框架,而是底部插入。 這顯然不能正常工作。
現在我將表視圖的底部約束設置為輸入視圖(黑色條)的頂部,將底部插入設置為零。 由於輸入視圖在鍵盤出現時向上移動,因此它會更改表格視圖的框架,並且底部插入保持為零。 我仍然設置內容偏移,因為我需要在不同情況下的特定行為,但就是這樣。
這只適用於我的情況,因為我既沒有半透明的輸入條也沒有鍵盤,也不需要在它后面顯示模糊的內容。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.