Welcome toVigges Developer Community-Open, Learning,Share
Welcome To Ask or Share your Answers For Others


0 votes
in Technique[技术] by (71.8m points)

ios - Detect when keyboard is fully visible and prevent keyboard appearance handling code from adding extra offset for hidden element

I want to know if the keyboard is fully visible and not if it's in in-between states of presentation. Unfortunately, all the answers use UIKeyboardDidShow, UIKeyboardWillShow, or UIKeyboardWillChangeFrame to check if keyboard is visible. All of these trigger listeners multiple times as the keyboard appears. So I can't use any of them to definitively tell if the keyboard is fully visible. I want to know if the keyboard is fully visible and prevent an action from triggering in my UIKeyboardWillShow listner.

let keyBoardHeight: CGFloat = 0

NotificationCenter.default.addObserver(self, selector: #selector(handleKeyboardWillChangeFrame), name: NSNotification.Name.UIKeyboardWillChangeFrame, object: nil)

    @objc func handleKeyboardWillChangeFrame(notification: NSNotification) {
        print("Keyboard notif called")
        guard let userInfo = notification.userInfo else { return }
        let uiScreenHeight = UIScreen.main.bounds.size.height
        let endFrame = (userInfo[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue
        let endFrameY = endFrame?.origin.y ?? 0
        let duration:TimeInterval = (userInfo[UIKeyboardAnimationDurationUserInfoKey] as? NSNumber)?.doubleValue ?? 0
        let animationCurveRawNSN = userInfo[UIKeyboardAnimationCurveUserInfoKey] as? NSNumber
        let animationCurveRaw = animationCurveRawNSN?.uintValue ?? UIView.AnimationOptions.curveEaseInOut.rawValue
        let animationCurve:UIView.AnimationOptions = UIView.AnimationOptions(rawValue: animationCurveRaw)
        let offset = -1 * (endFrame?.size.height ?? 0.0)

        print("Keyboard Height: ", keyBoardHeight, " End Frame Height: ", endFrame?.height ?? 0)
        if endFrameY >= uiScreenHeight {
            self.discussionsMessageBoxBottomAnchor.constant = 0.0
            discussionChatView.discussionTableView.contentOffset.y += 2 * offset
        } else 

          if keyBoardHeight != endFrame?.height ?? 0 // Extra check added to avoid triggering this part when keyboard is already fully visible

          //Once the keyboard is fully visible, any triggers of this method will find keyBoardHeight = endFrame?.height. What ends up happening is once the keyboard is fully shown, if the user again taps on the text view, this function gets triggered and execution enters the else part

            self.discussionsMessageBoxBottomAnchor.constant = offset
            discussionChatView.discussionTableView.contentOffset.y -= offset
        keyBoardHeight = max(keyBoardHeight, endFrame?.height ?? 0)
            withDuration: duration,
            delay: TimeInterval(0),
            options: animationCurve,
            animations: { self.view.layoutIfNeeded() },
            completion: nil)

Unfortunately, this is not producing the expected results. This is why I am looking for any other way to tell me if keyboard is fully visible. This will stop the keyboard appearance handling code from unnecessarily adding more offset to accommodate an already visible keyboard

Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Welcome to Vigges Developer Community for programmer and developer-Open, Learning and Share