Adarkas2302
Adarkas2302

Reputation: 1844

Keyboard notification not called with small keyboard

In my code the notifications, that the keyboard will open/close are called normally when the keyboard is big. But as soon as is make it small, squishing the keyboard between to fingers, those notifications are not called anymore. Anybody having similar issues?

That is how I observe the notifications:

let notificationCenter = NotificationCenter.default
notificationCenter.addObserver(self, selector: #selector(self.keyboardWillBeShown(_:)), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
notificationCenter.addObserver(self, selector: #selector(self.keyboardDidShown(_:)), name: NSNotification.Name.UIKeyboardDidShow, object: nil)
notificationCenter.addObserver(self, selector: #selector(self.keyboardWillBeHidden(_:)), name: NSNotification.Name.UIKeyboardWillHide, object: nil)

Upvotes: 1

Views: 308

Answers (3)

Jayesh Patel
Jayesh Patel

Reputation: 1104

notificationCenter.addObserver(self, selector: #selector(adjustForKeyboard), name: UIResponder.keyboardWillChangeFrameNotification, object: nil)

@objc func adjustForKeyboard(notification: Notification) {
    guard let keyboardValue = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue else { return }

    let keyboardScreenEndFrame = keyboardValue.cgRectValue
    let keyboardViewEndFrame = view.convert(keyboardScreenEndFrame, from: view.window)
     
    //You will get notifications event here
    if notification.name == UIResponder.keyboardWillHideNotification {
    
    } else {
   
    }
}

The adjustForKeyboard() method has quite a bit of work to do. First, it will receive a parameter that is of type Notification. This will include the name of the notification as well as a Dictionary containing notification-specific information called userInfo.

When working with keyboards, the dictionary will contain a key called UIResponder.keyboardFrameEndUserInfoKey telling us the frame of the keyboard after it has finished animating. This will be of type NSValue, which in turn is of type CGRect. The CGRect struct holds both a CGPoint and a CGSize, so it can be used to describe a rectangle.

Upvotes: 0

Hamad Fuad
Hamad Fuad

Reputation: 357

You should also register UIResponder.keyboardFrameEndUserInfoKey (A user info key to retrieve the keyboard's frame at the end of its animation.) to observe keyboard frame changes.

Upvotes: 0

Phil Dukhov
Phil Dukhov

Reputation: 88377

This is expected behavior. The keyboard by default reduces the size of the screen, so you have to squeeze items to make them fit.

But when you "squeeze the keyboard between your fingers", it starts to float over your views, so squeezing is no longer needed.

You can use the UIResponder.keyboardWillChangeFrameNotification to get keyboard appearances info like this:

func keyboardWillChangeFrame(_ notification: Notification) {
    guard
        let userInfo = notification.userInfo,
        let keyboardFrameEndRect = userInfo[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect,
        let animationCurveOption = userInfo[UIResponder.keyboardAnimationCurveUserInfoKey] as? Int
    else { return }
    print(keyboardFrameEndRect, animationCurveOption)
    if keyboardFrameEndRect.isEmpty || // Floating keyboard is HIDING or BEING DRAGGED by the user
        keyboardFrameEndRect.origin.y >= UIScreen.main.bounds.height // Split keyboard is moving off screen
    {
        // When animation curve is zero, the keyboard is being hidden. (Otherwise, it's being moved)
        if animationCurveOption != 0 {
            print("KEYBOARD IS HIDING")
        } else {
            // e.g. ignore
            print("FLOATING KEYBOARD IS MOVING")
        }
    } else {
        print("KEYBOARD IS SHOWING")
    }
}

p.s. UIResponder.keyboardWillChangeFrameNotification is following the current swift syntax instead of NSNotification.Name.UIKeyboardWillChangeFrame

Upvotes: 1

Related Questions