与此问题类似:
iPad: Detecting External Keyboard,我正在开发一个iPad应用程序,它使用带有自定义inputAccessoryView的文本字段来为虚拟键盘提供附加功能.
但是,如果硬件键盘(例如蓝牙键盘)连接到设备,则软件键盘未按预期显示,但由于某种原因,inputAccessoryView仍然在屏幕底部可见.此外,这似乎导致触发UIKeyboardDidShowNotification(并因此移动我的视图以避免键盘实际上不存在的遮挡),即使硬件键盘用于输入.
我找到了几种解决方案来检测是否连接了硬件键盘,但是在收到UIKeyboardDidShowNotification后它们都检查了状态,此时inputAccessoryView已经可见(例如How can I detect if an external keyboard is present on an iPad?).
我正在寻找一种方法,如果没有连接硬件键盘,只显示inputAccessoryView.因此,我需要知道在触发UIKeyboardDidShowNotification之前是否连接了硬件键盘.
这里提供的公认解决方案How can I detect if an external keyboard is present on an iPad?对我来说没有选择,因为他们使用私有API可能会导致我的应用被拒绝.
解决方法
这只是@arlomedia的答案的增强.我所做的是关注willShow和didShow.
我将使用willShow将我的textview移动到位,使其以与键盘相同的速率移动.
我用didShow来检查键盘的表观大小,使用上述技术并相应地隐藏/显示accessoryInputView.
重要的是我还默认将该视图设置为隐藏,并且当收到一个willHide事件时,它会再次被隐藏.
- (void) addKeyboardObserver { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardDidShow:) name:UIKeyboardDidShowNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardHidden:) name:UIKeyboardWillHideNotification object:nil]; } - (void) removeKeyboardObserver { [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardDidShowNotification object:nil]; [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil]; [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillHideNotification object:nil]; } - (void)keyboardWillShow:(NSNotification*)notification { CGSize keyboardSize = [[[notification userInfo] objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size; // If we're on iOS7 or earlier and landscape then the height is in the // width. // if ((IS_LANDSCAPE == YES) && (IS_IOS8_OR_LATER == NO)) { keyboardSize.height = keyboardSize.width; } NSNumber *rate = notification.userInfo[UIKeyboardAnimationDurationUserInfoKey]; CGRect textFieldFrame = self.textField.frame; textFieldFrame.origin.y = ([Util screenHeight] - keyboardSize.height) - textFieldFrame.size.height - [Util scaledHeight:10.0]; // Move the text field into place. // [UIView animateWithDuration:rate.floatValue animations:^{ self.answerTextField.frame = textFieldFrame; }]; keyboardShown = YES; } - (void)keyboardDidShow:(NSNotification*)notification { CGRect keyboardBeginFrame = [[[notification userInfo] objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue]; CGRect keyboardEndFrame = [[[notification userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue]; CGSize keyboardSize = keyboardBeginFrame.size; // If we're on iOS7 or earlier and landscape then the height is in the // width. // if ((IS_LANDSCAPE == YES) && (IS_IOS8_OR_LATER == NO)) { keyboardSize.height = ABS(keyboardBeginFrame.origin.x - keyboardEndFrame.origin.x); // the keyboard will move by an amount equal to its height when it appears; ABS is needed for upside-down orientations } else { keyboardSize.height = ABS(keyboardBeginFrame.origin.y - keyboardEndFrame.origin.y); // the keyboard will move by an amount equal to its height when it appears; ABS is needed for upside-down orientations } NSNumber *rate = notification.userInfo[UIKeyboardAnimationDurationUserInfoKey]; [UIView animateWithDuration:rate.floatValue animations:^{ if (keyboardSize.height <= self.accessoryBar.frame.size.height) { self.textField.inputAccessoryView.hidden = YES; self.answerTextField.inputAccessoryView.userInteractionEnabled = NO; } else { self.textField.inputAccessoryView.hidden = NO; self.answerTextField.inputAccessoryView.userInteractionEnabled = YES; } }]; keyboardShown = YES; } - (void)keyboardHidden:(NSNotification*)notification { NSNumber *rate = notification.userInfo[UIKeyboardAnimationDurationUserInfoKey]; // Remove/hide the accessory view so that next time the text field gets focus,if a hardware // keyboard is used,the accessory bar is not shown. // [UIView animateWithDuration:rate.floatValue animations:^{ self.textField.inputAccessoryView.hidden = YES; self.answerTextField.inputAccessoryView.userInteractionEnabled = NO; }]; keyboardShown = NO; }
注意编辑添加更改到userInteractionEnabled,以便隐藏的accessoryView不吃水龙头.