Я работаю над чатом, который должен работать на 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
Ограничения макета
Якоря табличного представления равны якорям его суперпредставления,Так что на весь экран, игнорируя безопасную зону.Поэтому, когда появляется клавиатура, рамка не меняется, а нижний контент вставляется.
Подробнее
Я установил 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
сумму, которая точно соответствуетвысота клавиатуры.