Pourquoi observer onKeyboardDisplayed est appelé avant textViewDidBeginEditing

Dec 23 2020

Mon application est rapide. Lorsque j'édite un UITextField, le clavier masque parfois le champ. J'utilise donc le délégué textFieldDidBeginEditing pour définir un "activeTextField" (et textFieldDidEndEditing pour le remettre à zéro). Puis sur viewDidLoad j'ajoute un observateur lié à une fonction onKeyboardDisplayed où je teste la valeur de "activeTextField" afin que je puisse faire glisser l'écran vers le haut si nécessaire. Et ça marche bien :)

La mauvaise nouvelle est que j'ai essayé de faire la même chose pour un UITextView, en utilisant le délégué textViewDidBeginEditing pour définir un "activeTextView". Mais contrairement à UITextField, le délégué est appelé après onKeyboardDisplayed afin que le clavier masque toujours mon 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)
        }
    }
}

Connaissez-vous un moyen de résoudre ce problème?

Réponses

2 syntiz Dec 23 2020 at 20:36

Enfin, j'ai trouvé une solution ici: les événements de clavier appelés avant les événements de délégué UITextView

J'ai changé de clavier

NotificationCenter.default.addObserver(self, selector: #selector(onKeyboardDisplayed(notification:)), name: UIResponder.keyboardWillShowNotification, object: nil)

par keyboardDidShowNotification

NotificationCenter.default.addObserver(self, selector: #selector(onKeyboardDisplayed(notification:)), name: UIResponder.keyboardDidShowNotification, object: nil)

Et maintenant cela fonctionne bien: ma fonction onKeyboardDisplayed est appelée après le délégué textViewDidBeginEditing

1 LucaSfragara Dec 23 2020 at 18:54

La manière standard de traiter le clavier qui apparaît est la suivante

Dans votre 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
}

Cela déplace le cadre de vue vers le haut et vers le bas en fonction de la hauteur du clavier. Si je comprends bien votre question, je pense que cela peut vous aider