After fiddling with a iPad for an hour, I finally have a good solution for this in swift. The other methods are weak or use 3rd party software. The reason why UIKeyboardWillShowNotification
is getting fired even when an external keyboard is being used for an iPad is the shortcut bar existing. In order to disable the shortcut bar, do this:
let item : UITextInputAssistantItem = textField.inputAssistantItem
item.leadingBarButtonGroups = []
item.trailingBarButtonGroups = []
This covers most cases of what you need, but UIKeyboardWillShowNotification
can still be fired if someone plugs their keyboard in at certain points of use. If you have the screen adjust, you can't afford any case for the user to experience this. Plus, you might want the shortcut bar for some reason. Regardless of what your desires are, this covers all cases of an external keyboard being used:
Add to viewDidAppear
NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(LoginViewController.keyboardWillShow), name: UIKeyboardWillShowNotification, object: nil)
NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(LoginViewController.keyboardWillHide), name: UIKeyboardWillHideNotification, object: nil)
whenever you leave the view add this to anything that makes you leave
NSNotificationCenter.defaultCenter().removeObserver(self, name: UIKeyboardWillShowNotification, object: nil)
NSNotificationCenter.defaultCenter().removeObserver(self, name: UIKeyboardWillHideNotification, object: nil)
also add it to the deinit{}
method to be thourough.
Now use these functions:
func keyboardWillShow(notification: NSNotification) {
// This code is an alternate way of checking for keyboard
var userInfo: [NSObject: AnyObject] = notification.userInfo!
let firstFrame = userInfo[UIKeyboardFrameBeginUserInfoKey] as! NSValue
let secondFrame = userInfo[UIKeyboardFrameEndUserInfoKey] as! NSValue
let firstRect = firstFrame.CGRectValue()
let secondRect = secondFrame.CGRectValue()
let diff = abs(firstRect.origin.y - secondRect.origin.y)
let isFirstBigger = firstRect.origin.y > secondRect.origin.y
if firstRect != secondRect && diff != 55 {
if !isFirstBigger {
//animateViewToDefaultPosition()
} else {
//animateViewToPositionWhenKeyboardActive()
}
}
}
func keyboardWillHide() {
//animateViewToDefaultPosition()
}
The 55 is the height of the shortcut bar. You can remove it's functionality if you don't have one. The !isFirstBigger
is used to check for when they unhook the keyboard and hook it back in during text field editing. It is also important that diff != 55
during that check because with a shortcut bar this would be the case when you did not want to animate the screen.
This is by far the best method I have seen after scouring Stack Overflow. If anyone finds a bug in the functionality, let me know, but I am confident it will take care of the pesky shortcut bar external keyboard issues. I hope this helps everyone else out there confused by all this!