Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/facebook/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios UIKeyboardDidShowNotification多次调用,有时键盘尺寸不正确_Ios_Uikeyboard_Nsnotification - Fatal编程技术网

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

Ios UIKeyboardDidShowNotification多次调用,有时键盘尺寸不正确,ios,uikeyboard,nsnotification,Ios,Uikeyboard,Nsnotification,每当键盘出现/更改时,我尝试将UITextView移到键盘上方。比方说,我显示了英文键盘,然后直接切换到中文键盘(比标准英文键盘高)。在这种情况下,我的文本视图总是显得太高(在肉眼看来,似乎文本视图被中文键盘“输入附件视图”的大小错误地偏移了。我会发布一张图片,但没有这样做的声誉:)。当我的应用程序收到UIKeyboardDidShowNotification(使用UIKeyboardFrameEndUserInfoKey获取高度)时,我正在调整我的文本视图位置,经过一些调查后,UIKeyboa

每当键盘出现/更改时,我尝试将UITextView移到键盘上方。比方说,我显示了英文键盘,然后直接切换到中文键盘(比标准英文键盘高)。在这种情况下,我的文本视图总是显得太高(在肉眼看来,似乎文本视图被中文键盘“输入附件视图”的大小错误地偏移了。我会发布一张图片,但没有这样做的声誉:)。当我的应用程序收到UIKeyboardDidShowNotification(使用UIKeyboardFrameEndUserInfoKey获取高度)时,我正在调整我的文本视图位置,经过一些调查后,UIKeyboardDidShowNotification被多次调用,通常使用不正确的键盘尺寸(我已记录userInfo字典)。我在视图中注册键盘通知将出现,在视图中取消注册将消失。我无法确定是什么原因导致此通知多次发出;我的理解是,此通知只应在键盘完成显示后触发一次。另一个注意事项:我在响应UIKeyboardDidShowNotification的方法中记录了“self”,实际上它始终是同一个视图控制器对象

但是,即使此通知多次触发,我仍然不理解为什么某些通知的键盘高度会有所不同。其中一个通知始终具有正确的高度,但当它不是最后一个触发的通知时,文本视图将出现在错误的位置。任何关于如何进一步排除故障的见解都将不胜感激

编辑:我测试得越多,中文键盘就越有问题。每当我将键盘从英文切换到中文时,我都会收到三个UIKeyboard显示通知:

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处不正确。这是可靠的

以下是几个片段,演示我如何管理通知订阅:

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

该解决方案来自苹果的官方解决方案,如曹 说。

在我的情况下,我在视图中注册的键盘通知将出现,在视图中取消注册也将消失。但是,它将导致UIKeyboardDidShowNotification处理程序被激发多次。似乎unregister方法不起作用,因此,每次视图出现时,UIKeyboardDidShowNotification的观察者计数加上1。然后,触摸UITextField内部,将通知多个观察者,并一次又一次地触发处理程序

因此,您必须在ViewDidLoad中注册键盘通知,而不要取消注册。就像这篇文章中提到的苹果一样

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

我认为“设置”意味着ViewDidLoad。在处理键盘通知代码列表中,没有视图会消失

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

   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
}

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

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


如果您改为使用键盘的
返回
按钮,那么它将做正确的事情并放弃它。

我也经历过设置文本字段的自定义inputView(UIPickerView)。我已经确定了问题和解决方法。在响应UIKeyboardWillShow通知而调用的方法中,我在动画块内调用[self.view layoutSubviews]。当我为LayoutSubView设置动画时,附加的UIKeyboardWillShow通知会被我问题中发布的奇怪值触发。如果在动画块外部调用[self.view layoutSubviews],则只会触发一次通知,且该值始终正确。所以,如果没有动画,这很好,但我仍然不明白为什么它不能正确地与动画一起工作。我面临着同样的问题!在我的测试中,英文/日文键盘没有问题,只有中文键盘有时会被多次调用,并且尺寸错误。我放弃了让它与动画一起工作。但是它在没有任何限制的情况下确实能持续工作,所以我对解决方案相对满意。我认为它不仅限于中国人,但不确定。这是一个很好的答案,但没有什么具体的。不敢相信有人否决了这个答案。的确,对于Cmd+K,它被调用两次。谢谢
   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
}