1

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?

syntiz
  • 75
  • 5

2 Answers2

2

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

syntiz
  • 75
  • 5
1

The standard way of dealing with the keyboard appearing is this

In your 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
}

This moves the view frame up and down according to the height of the keyboard. If I understand your question correctly, I believe this can help you

Luca Sfragara
  • 624
  • 4
  • 16
  • Thanks, this already the pattern I use. I forgot to explain that my function "onKeyboardDisplayed" is called via observer, the same way as your handleKeyboardWillShow. But I don't want to move the view frame up if my field is not covered by the keyboard. So I have to compute the position of "active field". I will update my question to be more clear. – syntiz Dec 23 '20 at 13:14
  • Okay, that's good. Well done on posting the answer to your own question!! – Luca Sfragara Dec 23 '20 at 17:08