Por que o observador onKeyboardDisplayed é chamado antes de textViewDidBeginEditing
Meu aplicativo está em alta. Quando edito um UITextField, às vezes o teclado oculta o campo. Portanto, uso o delegado textFieldDidBeginEditing para definir um "activeTextField" (e textFieldDidEndEditing para redefini-lo como nulo). Em seguida, em viewDidLoad, adiciono um observador vinculado a uma função onKeyboardDisplayed onde testo o valor de "activeTextField" para poder deslizar a tela para cima, se necessário. E funciona bem :)
A má notícia é que tentei fazer o mesmo para um UITextView, usando o delegado textViewDidBeginEditing para definir um "activeTextView". Mas, ao contrário de UITextField, o delegado é chamado depois de onKeyboardDisplayed, de forma que o teclado ainda oculta meu UITextView.
NotificationCenter.default.addObserver(self, selector: #selector(onKeyboardDisplayed(notification:)), name: UIResponder.keyboardWillShowNotification, object: nil)
@objc func onKeyboardDisplayed(notification: Notification) {
guard let keyboardRect = (notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue else {
return
}
var visibleRect : CGRect = self.view.frame
visibleRect.size.height -= keyboardRect.height
if (activeTextField != nil) {
// Get y position of active textField bottom.
let textFieldBottomPosition = activeTextField!.convert(CGPoint.zero, to: nil).y + activeTextField!.frame.height
if(textFieldBottomPosition > visibleRect.size.height) {
// swipe up
view.frame.origin.y = (visibleRect.size.height - textFieldBottomPosition - 6)
}
}
if (activeTextView != nil) {
// Get y position of active textView bottom.
let textViewBottomPosition = activeTextView!.convert(CGPoint.zero, to: nil).y + activeTextView!.frame.height
if(textViewBottomPosition > visibleRect.size.height) {
// swipe up
view.frame.origin.y = (visibleRect.size.height - textViewBottomPosition - 6)
}
}
}
Você conhece uma maneira de consertar isso?
Respostas
Finalmente encontrei uma solução aqui: eventos de teclado chamados antes dos eventos de delegado UITextView
Eu mudei keyboardWillShowNotification
NotificationCenter.default.addObserver(self, selector: #selector(onKeyboardDisplayed(notification:)), name: UIResponder.keyboardWillShowNotification, object: nil)
por keyboardDidShowNotification
NotificationCenter.default.addObserver(self, selector: #selector(onKeyboardDisplayed(notification:)), name: UIResponder.keyboardDidShowNotification, object: nil)
E agora funciona bem: minha função onKeyboardDisplayed é chamada após o delegado textViewDidBeginEditing
A maneira padrão de lidar com a aparência do teclado é esta
Em seu ViewController:
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(handleKeyboardWillShow), name: UIControl.keyboardWillShowNotification, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(handleKeyboardWillHide), name: UIControl.keyboardWillHideNotification, object: nil)
}
@objc private func handleKeyboardWillShow(notification: NSNotification){
guard let keyboardSize = (notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue else{
return
}
self.view.frame.origin.y -= keyboardSize.height
}
@objc private func handleKeyboardWillHide(notification: NSNotification){
self.view.frame.origin.y = 0
}
Isso move o quadro de exibição para cima e para baixo de acordo com a altura do teclado. Se entendi sua pergunta corretamente, acredito que isso pode ajudá-lo