Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
4.9k views
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)
        
        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


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)
等待大神解答

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

57.0k users

...