Dlaczego obserwator onKeyboardDisplayed jest wywoływany przed textViewDidBeginEditing

Dec 23 2020

Moja aplikacja działa szybko. Kiedy edytuję UITextField, czasami klawiatura ukrywa to pole. Więc używam delegata textFieldDidBeginEditing, aby ustawić "activeTextField" (i textFieldDidEndEditing, aby zresetować go do zera). Następnie w viewDidLoad dodaję obserwatora połączonego z funkcją onKeyboardDisplayed, w której testuję wartość „activeTextField”, więc w razie potrzeby mogę przesunąć ekran w górę. I działa dobrze :)

Złą nowością jest to, że próbowałem zrobić to samo dla UITextView, używając delegata textViewDidBeginEditing do ustawienia „activeTextView”. Ale w przeciwieństwie do UITextField delegat jest wywoływany po onKeyboardDisplayed, więc klawiatura nadal ukrywa mój 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)
        }
    }
}

Czy znasz sposób, aby to naprawić?

Odpowiedzi

2 syntiz Dec 23 2020 at 20:36

Wreszcie znalazłem tutaj rozwiązanie: zdarzenia klawiatury wywołane przed zdarzeniami delegatów UITextView

Zmieniłem keyboardWillShowNotification

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

przez keyboardDidShowNotification

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

A teraz działa dobrze: moja funkcja onKeyboardDisplayed jest wywoływana po delegacie textViewDidBeginEditing

1 LucaSfragara Dec 23 2020 at 18:54

Standardowy sposób radzenia sobie z pojawianiem się klawiatury jest taki

W Twoim 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
}

Spowoduje to przesunięcie ramki widoku w górę iw dół zgodnie z wysokością klawiatury. Jeśli dobrze zrozumiem twoje pytanie, uważam, że może ci to pomóc