UIKeyboardDidShowNotification多次调用,有时使用不正确的键盘尺寸

我试图在键盘出现/更改时移动键盘上方的UITextView。 比方说,我有英文键盘显示,然后直接切换到中文键盘(这是比标准的英文键盘高)。 在这种情况下,我的文本视图总是显得过高(肉眼看来,文本视图不正确地偏移了中文键盘的大小“input配件视图”),我会张贴图像,但缺乏声誉所以:))。 当我的应用程序收到一个UIKeyboardDidShowNotification(使用UIKeyboardFrameEndUserInfoKey获取高度),以及一些调查UIKeyboardDidShowNotification被调用多次,经常与不正确的键盘尺寸 (我NSLogged userInfo字典)调整我的文本视图位置。 我在ViewWillAppear中注册我的键盘通知,并在ViewWillDisappear中取消注册。 我无法确定什么可能导致此通知多次触发; 我的理解是这个通知只能在键盘完成显示之后被触发一次。 另外需要注意的是:在响应UIKeyboardDidShowNotification的方法中,我已经NSLogged'self',事实上它总是与View Controller Object相同。

但是,即使这个通知多次触发,我仍然不明白为什么键盘高度会因这些通知中的一些而不同。 其中一个通知总是有正确的高度,但是当它不是最后一个通知时,文本视图结束了错误的地方。 任何有关如何进一步排除故障的见解将不胜感激!

编辑:我testing越多,似乎是与中文键盘具体问题。 每当我把键盘从英文切换到中文,我得到三个UIKeyboardWillShowNotifications:

2014-12-24 22:49:29.385 Example[1055:421943] info dictionary: { UIKeyboardAnimationCurveUserInfoKey = 0; UIKeyboardAnimationDurationUserInfoKey = 0; UIKeyboardBoundsUserInfoKey = "NSRect: {{0, 0}, {320, 252}}"; UIKeyboardCenterBeginUserInfoKey = "NSPoint: {160, 460}"; UIKeyboardCenterEndUserInfoKey = "NSPoint: {160, 442}"; UIKeyboardFrameBeginUserInfoKey = "NSRect: {{0, 352}, {320, 216}}"; UIKeyboardFrameEndUserInfoKey = "NSRect: {{0, 316}, {320, 252}}"; } 2014-12-24 22:49:29.408 Example[1055:421943] info dictionary: { UIKeyboardAnimationCurveUserInfoKey = 0; UIKeyboardAnimationDurationUserInfoKey = 0; UIKeyboardBoundsUserInfoKey = "NSRect: {{0, 0}, {320, 216}}"; UIKeyboardCenterBeginUserInfoKey = "NSPoint: {160, 442}"; UIKeyboardCenterEndUserInfoKey = "NSPoint: {160, 460}"; UIKeyboardFrameBeginUserInfoKey = "NSRect: {{0, 316}, {320, 252}}"; UIKeyboardFrameEndUserInfoKey = "NSRect: {{0, 352}, {320, 216}}"; } 2014-12-24 22:49:29.420 Example[1055:421943] info dictionary: { UIKeyboardAnimationCurveUserInfoKey = 0; UIKeyboardAnimationDurationUserInfoKey = 0; UIKeyboardBoundsUserInfoKey = "NSRect: {{0, 0}, {320, 288}}"; UIKeyboardCenterBeginUserInfoKey = "NSPoint: {160, 442}"; UIKeyboardCenterEndUserInfoKey = "NSPoint: {160, 424}"; UIKeyboardFrameBeginUserInfoKey = "NSRect: {{0, 316}, {320, 252}}"; UIKeyboardFrameEndUserInfoKey = "NSRect: {{0, 280}, {320, 288}}"; } 

第一个有正确的结束高度:252.然而,接下来的两个在216和288是不正确的。

这里有几个片段来演示我如何pipe理订阅通知:

 -(void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; [self registerForKeyboardNotifications]; } -(void)viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated]; [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillHideNotification object:nil]; [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardDidShowNotification object:nil]; } - (void)registerForKeyboardNotifications { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardDidHide:) name:UIKeyboardWillHideNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardDidShow:) name:UIKeyboardDidShowNotification object:nil]; } 

如果您在模拟器上使用Cmd + K快捷键来显示/隐藏键盘,则可能会多次调用它,因为它不会将文本字段作为第一响应者。

如果你使用键盘的Returnbutton,那么它会做正确的事情,并辞职。

SWIFT答案:主要原因是您的通知被多次调用。 例如,在swift中,如果在viewWillAppear方法内部有NSNotificationCenter.defaultCenter()。addObserver(xx“keyboardWillShow”xx),并且如果在视图之间来回切换,则会导致多个观察者具有相同的“ keyboardWillShow”。 相反,您应该考虑将addObserver调用移动到“viewDidLoad()”方法。 或者,您可以在视图出现/消失时注册/取消注册观察者。

在我的情况下, 我在ViewWillAppear中注册我的键盘通知,并在ViewWillDisappear中取消注册 。 但是,这会导致UIKeyboardDidShowNotification处理程序被多次触发。 好像注销方法不起作用,所以,每次出现视图时,UIKeyboardDidShowNotification的Observer计数加1.然后,在UITextField内部触摸,多个Observer被通知,处理程序被一次又一次地触发。

因此,您必须在ViewDidLoad中注册键盘通知,并且不要取消注册。 就像本页提到的苹果一样,

//在你的视图控制器设置代码的某个地方调用这个方法。

我认为“设置”意味着ViewDidLoad.And在处理键盘通知代码列表中,没有ViewWillDisappear。

这是我的键盘通知处理程序,它的工作。

  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 } 
 - (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; } 

曹说,解决scheme来自苹果的官方解决scheme。