textViewDidBeginEditingの前にオブザーバーonKeyboardDisplayedが呼び出される理由

Dec 23 2020

私のアプリは迅速です。UITextFieldを編集すると、キーボードがフィールドを非表示にすることがあります。そこで、デリゲートtextFieldDidBeginEditingを使用して「activeTextField」を設定します(そしてtextFieldDidEndEditingを使用してnilにリセットします)。次に、viewDidLoadで、onKeyboardDisplayed関数にリンクされたオブザーバーを追加します。ここで、「activeTextField」の値をテストして、必要に応じて画面を上にスワイプできるようにします。そしてそれはうまくいきます:)

悪い新機能は、デリゲートtextViewDidBeginEditingを使用して「activeTextView」を設定し、UITextViewに対して同じことを試みたことです。ただし、UITextFieldとは異なり、デリゲートはonKeyboardDisplayedの後に呼び出されるため、キーボードは引き続き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)
        }
    }
}

それを修正する方法を知っていますか?

回答

2 syntiz Dec 23 2020 at 20:36

最後に、ここで解決策を見つけました:UITextViewデリゲートイベントの前に呼び出されるキーボードイベント

私はkeyboardWillShowNotificationを変更しました

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

によってkeyboardDidShowNotification

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

そして今、それはうまく機能します:私のonKeyboardDisplayed関数はデリゲートtextViewDidBeginEditingの後に呼び出されます

1 LucaSfragara Dec 23 2020 at 18:54

表示されるキーボードを処理する標準的な方法はこれです

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
}

これにより、キーボードの高さに応じてビューフレームが上下に移動します。私があなたの質問を正しく理解していれば、これはあなたを助けることができると信じています