swiftuitextviewuikeyboarduitextviewdelegate

Why observer onKeyboardDisplayed is called before textViewDidBeginEditing


My App is in swift. When I edit a UITextField, sometimes the keyboard hides the field. So I use the delegate textFieldDidBeginEditing to set an "activeTextField" (and textFieldDidEndEditing to reset it to nil). Then on viewDidLoad I add an observer linked to a onKeyboardDisplayed function where I test the value of "activeTextField" so I can swipe the screen up if needed. And it works well :)

The bad new is that I tried to do the same for a UITextView, using delegate textViewDidBeginEditing to set an "activeTextView". But unlike UITextField, the delegate is called after onKeyboardDisplayed so the keyboard still hides my 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)
        }
    }
}

Do you know a way to fix that?


Solution

  • Finally I found a solution here: Keyboard events called before UITextView delegate events

    I changed keyboardWillShowNotification

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

    by keyboardDidShowNotification

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

    And now it works well: my onKeyboardDisplayed function is called after the delegate textViewDidBeginEditing