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

纵饮孤独 提交于 2021-01-29 05:41:02

问题


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)
        
        UIView.animate(
            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

来源:https://stackoverflow.com/questions/65749069/detect-when-keyboard-is-fully-visible-and-prevent-keyboard-appearance-handling-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!