I am trying to move a UITextView above the keyboard whenever the keyboard appears/changes. Let\'s say I have the English keyboard displaying and then switch directly to the Chin
The primary reason is that the your notification is invoked multiple times. For example, in swift, if you had the NSNotificationCenter.defaultCenter().addObserver(xx"keyboardWillShow"xx) inside viewWillAppear method and if you are going back and forth between the view then it will result in having multiple observer of the same "keyboardWillShow". Instead you should consider moving the addObserver call to "viewDidLoad()" method. Alternatively you can register/deregister observer when the view appears/disappears.
- (void)keyboardDidAppear:(NSNotification *)note {
CGSize keyboardSize = [note.userInfo[UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0, keyboardSize.height, 0.0);
textView.contentInset = contentInsets;
textView.scrollIndicatorInsets = contentInsets;
}
- (void)keyboardWillBeHidden:(NSNotification *)note {
UIEdgeInsets contentInsets = UIEdgeInsetsZero;
textView.contentInset = contentInsets;
textView.scrollIndicatorInsets = contentInsets;
}
The solution is from Apple's official solution here like 曹 said.
In my case, I register for my keyboard notifications in ViewWillAppear and unregister in ViewWillDisappear too. But, It will cause the UIKeyboardDidShowNotification handler be fired multiple times. Seem like the unregister method do not work, so, every time the view appears, the counts of Observer for UIKeyboardDidShowNotification plus 1. Then, you touch inside UITextField, multiple Observer be notified, handler be fired again and again.
So, you must register for keyboard notifications in ViewDidLoad and don't unregister. Just like the Apple mentioned in this page,
// Call this method somewhere in your view controller setup code.
I think the 'setup' means ViewDidLoad.And In the Handling the keyboard notifications code list,no ViewWillDisappear.
Here's my handler for keyboard notify, and it work.
func keyboardWillShow(notification: NSNotification) {
let userInfo = notification.userInfo!
let keyboardHeight = (userInfo[UIKeyboardFrameEndUserInfoKey] as! NSValue).CGRectValue().height
debugPrint("Before",NotifyView.frame)
NotifyView.frame.offsetInPlace(dx: 0, dy: -keyboardHeight)
debugPrint("After",NotifyView.frame)
}
func keyboardWillHide(notification: NSNotification) {//Do Nothing
}
If you're using the Cmd+K shortcut on the simulator to show/hide the keyboard, it may get called multiple times since that doesn't resign the textfield as the first responder.
If you instead use the keyboard's Return
button then it will do the right thing and resign it.