Изменение размера экрана при появлении клавиатуры
Я создаю приложение чата. Я должен переместить текстовое поле, когда появляется клавиатура. Я делаю это с помощью следующего кода:
func keyboardWillShow(notification: NSNotification) {
if let userInfo = notification.userInfo {
if let keyboardSize = (userInfo[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue() {
kbHeight = keyboardSize.height
self.animateTextField(true)
}
}
}
func keyboardWillHide(notification: NSNotification) {
self.animateTextField(false)
}
func animateTextField(up: Bool) {
var movement = (up ? -kbHeight : kbHeight)
UIView.animateWithDuration(0.3, animations: {
self.view.frame = CGRectOffset(self.view.frame, 0, movement)
})
}
Но когда я использую этот код, первые сообщения не отображаются. Я думаю, мне нужно изменить размер таблицы.
Вот скриншоты До и После появляется клавиатура:
Я использую автоматическую разметку.
Как я могу решить эту проблему?
Ответы
Ответ 1
Вы можете создать выход из нижнего ограничения макета в виде таблицы.
Затем просто используйте этот код:
func keyboardWillShow(sender: NSNotification) {
let info = sender.userInfo!
var keyboardSize = (info[UIKeyboardFrameEndUserInfoKey] as! NSValue).cgRectValue.height
bottomConstraint.constant = keyboardSize - bottomLayoutGuide.length
let duration: TimeInterval = (info[UIKeyboardAnimationDurationUserInfoKey] as! NSNumber).doubleValue
UIView.animate(withDuration: duration) { self.view.layoutIfNeeded() }
}
func keyboardWillHide(sender: NSNotification) {
let info = sender.userInfo!
let duration: TimeInterval = (info[UIKeyboardAnimationDurationUserInfoKey] as! NSNumber).doubleValue
bottomConstraint.constant = 0
UIView.animate(withDuration: duration) { self.view.layoutIfNeeded() }
}
Если у вас возникли проблемы с созданием нижнего ограничения:
В раскадровке
- Выберите строку поиска.
- На углу в правом нижнем углу вы увидите 3 значка. Нажмите средний, похожий на
|-[]-|
.
- В верхней части этого всплывающего окна есть 4 окна. Введите 0 в нижний.
- Создан Constraint!
Теперь вы можете перетащить его в свой контроллер просмотра и добавить его как выход.
Другим решением является установка tableView.contentInset.bottom
. Но я этого не делал раньше. Если вы предпочитаете это, я могу попытаться объяснить это.
Использование вставки:
func keyboardWillShow(sender: NSNotification) {
let info = sender.userInfo!
let keyboardSize = (info[UIKeyboardFrameEndUserInfoKey] as! NSValue).cgRectValue.height
tableView.contentInset.bottom = keyboardSize
}
func keyboardWillHide(sender: NSNotification) {
tableView.contentInset.bottom = 0
}
Вы можете попробовать этот код для установки вставки. Я еще не пробовал это сам, но это должно быть что-то вроде этого.
EDIT: Изменена продолжительность с помощью nacho4d
Ответ 2
ОБНОВЛЕНИЕ 2017/2019
Есть только один способ правильно справиться с этим беспорядком в iOS.
1) Вставьте KUIViewController в свой проект,
2) Создайте ограничение, которое просто находится в "нижней части вашего контента". Обсуждается ниже.
3) Перетащите идентификатор ограничения на bottomConstraintForKeyboard
KUIViewController будет автоматически и правильно изменять размер вашего контента в любое время.
Вопрос решен.
Так "какой вид вы должны изменить размер?"
Вы не можете использовать .view
. Потому что вы не можете изменить размер .view
в iOS!
Просто сделайте UIView с именем "держатель". Он сидит внутри .view
.
Положите все свое в держателе.
Держатель, конечно, будет иметь четыре простых ограничения сверху/снизу/слева/справа до .view
.
Это нижнее ограничение для "держателя" действительно bottomConstraintForKeyboard
.
Вы сделали Отправьте счет клиенту и пейте. Больше нечего делать.
Проблема 2... щелкнув "фон", чтобы очистить клавиатуру
Обычно в современном UX, если вы нажмете "выкл" - так: подальше от каких-либо кнопок, полей ввода - он должен отклонить клавиатуру.
Класс KUIViewController
полностью автоматизирует это. Ничего не делать.
class KUIViewController: UIViewController {
// KBaseVC is the KEYBOARD variant BaseVC. more on this later
@IBOutlet var bottomConstraintForKeyboard: NSLayoutConstraint!
@objc func keyboardWillShow(sender: NSNotification) {
let i = sender.userInfo!
let k = (i[UIResponder.keyboardFrameEndUserInfoKey] as! NSValue).cgRectValue.height
bottomConstraintForKeyboard.constant = k - bottomLayoutGuide.length
let s: TimeInterval = (i[UIResponder.keyboardAnimationDurationUserInfoKey] as! NSNumber).doubleValue
UIView.animate(withDuration: s) { self.view.layoutIfNeeded() }
}
@objc func keyboardWillHide(sender: NSNotification) {
let info = sender.userInfo!
let s: TimeInterval = (info[UIResponder.keyboardAnimationDurationUserInfoKey] as! NSNumber).doubleValue
bottomConstraintForKeyboard.constant = 0
UIView.animate(withDuration: s) { self.view.layoutIfNeeded() }
}
@objc func clearKeyboard() {
view.endEditing(true)
}
func keyboardNotifications() {
NotificationCenter.default.addObserver(self,
selector: #selector(keyboardWillShow),
name: UIResponder.keyboardWillShowNotification,
object: nil)
NotificationCenter.default.addObserver(self,
selector: #selector(keyboardWillHide),
name: UIResponder.keyboardWillHideNotification,
object: nil)
}
override func viewDidLoad() {
super.viewDidLoad()
keyboardNotifications()
let t = UITapGestureRecognizer(target: self, action: #selector(clearKeyboard))
view.addGestureRecognizer(t)
t.cancelsTouchesInView = false
}
}
Ты...
Используйте KUIViewController везде, где может появиться клавиатура.
class AddCustomer: KUIViewController, SomeProtocol {
class CustomerPicker: KUIViewController {
На этих экранах абсолютно все теперь полностью автоматизировано. Конец истории.
* Незначительная сноска - фоновые щелчки правильно отклоняют клавиатуру. Это включает в себя клики, которые попадают на ваш контент. Это правильное поведение Apple. Любое необычное изменение потребовало бы специального программирования.
Ответ 3
Из сообщения @Fattie:
Детали - (к сожалению) клики по вашему контенту также отклонят клавиатуру. (Они оба получают событие.) Однако это почти всегда правильное поведение; попробуйте. Нет разумного избежать этого, поэтому забудьте об этом и идите с потоком Apple.
Это можно решить, выполнив следующий метод UIGestureRecognizerDelegate:
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
return !(touch.view?.isKind(of: UIControl.self) ?? true)
}
Таким образом, если пользователь коснется любого UIControl
(UIButton, UITextField и т.д.), распознаватель жестов не вызовет метод clearKeyboard()
.
Чтобы это сработало, запомните подкласс UIGestureRecognizerDelegate либо в определении класса, либо с расширением. Затем в viewDidLoad() вы должны назначить делегат распознавателя жестов как self.
Готов к копированию и вставке кода:
// 1. Subclass UIGestureRecognizerDelegate
class KUIViewController: UIViewController, UIGestureRecognizerDelegate {
@IBOutlet var bottomConstraintForKeyboard: NSLayoutConstraint!
func keyboardWillShow(sender: NSNotification) {
let i = sender.userInfo!
let k = (i[UIKeyboardFrameEndUserInfoKey] as! NSValue).cgRectValue.height
bottomConstraintForKeyboard.constant = k - bottomLayoutGuide.length
let s: TimeInterval = (i[UIKeyboardAnimationDurationUserInfoKey] as! NSNumber).doubleValue
UIView.animate(withDuration: s) { self.view.layoutIfNeeded() }
}
func keyboardWillHide(sender: NSNotification) {
let info = sender.userInfo!
let s: TimeInterval = (info[UIKeyboardAnimationDurationUserInfoKey] as! NSNumber).doubleValue
bottomConstraintForKeyboard.constant = 0
UIView.animate(withDuration: s) { self.view.layoutIfNeeded() }
}
func keyboardNotifications() {
NotificationCenter.default.addObserver(self,
selector: #selector(keyboardWillShow),
name: Notification.Name.UIKeyboardWillShow,
object: nil)
NotificationCenter.default.addObserver(self,
selector: #selector(keyboardWillHide),
name: Notification.Name.UIKeyboardWillHide,
object: nil)
}
func clearKeyboard() {
view.endEditing(true)
}
override func viewDidLoad() {
super.viewDidLoad()
keyboardNotifications()
let t = UITapGestureRecognizer(target: self, action: #selector(clearKeyboard))
view.addGestureRecognizer(t)
t.cancelsTouchesInView = false
// 2. Set the gesture recognizer delegate as self
t.delegate = self
}
// 3. Implement this method from UIGestureRecognizerDelegate
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
return !(touch.view?.isKind(of: UIControl.self) ?? true)
}
}
Ответ 4
если вы не хотите драться с этим сами, вы можете найти TPKeyboardAvoiding framework
Просто следуйте инструкциям по установке, то есть перетащите соответствующие файлы .h/.m в свой проект, а затем сделайте ScrollView/TableView подклассом, как показано ниже:
![Custom Class]()