在iOS 9之前,确定是否连接了外部键盘的最可靠方法是监听UIKeyboardWillShowNotification并使文本字段成为第一响应者,如this question中所述.使用虚拟键盘时会发出通知,但使用外部键盘时不会发出通知.

然而,iOS 9现在改变了这种行为.UIKeyboardWillShowNotification在连接外部键盘时也会触发,因为现在显示了新的键盘工具栏.

仍然可以检测键盘高度,并判断显示的是较小的工具栏还是较大的虚拟键盘.然而,这种方法并不可靠,因为键盘高度在不同的测试版之间发生了变化,不能指望随着时间的推移保持不变.

有没有更可靠的方法可以用于iOS 9?

推荐答案

回到原来的问题,我找到了一个有效的解决方案.

当显示常规虚拟键盘时,键盘框架似乎在屏幕的尺寸范围内.但是,当连接物理键盘并显示键盘工具栏时,键盘框架位于屏幕外.我们可以判断键盘框是否在屏幕外,以确定键盘工具栏是否显示.

Objective-C

- (void) keyboardWillShow:(NSNotification *)notification {
    NSDictionary* userInfo = [notification userInfo];
    CGRect keyboardFrame = [[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
    CGRect keyboard = [self.view convertRect:keyboardFrame fromView:self.view.window];
    CGFloat height = self.view.frame.size.height;

    if ((keyboard.origin.y + keyboard.size.height) > height) {
        self.hasKeyboard = YES;
    }
}

Swift

@objc func keyboardWillShow(_ notification: NSNotification) {
    guard let userInfo = notification.userInfo else {return}
    let keyboardScreenEndFrame = (userInfo[UIResponder.keyboardFrameEndUserInfoKey] as! NSValue).cgRectValue
    let keyboard = self.view.convert(keyboardScreenEndFrame, from: self.view.window)
    let height = self.view.frame.size.height
    if (keyboard.origin.y + keyboard.size.height) > height {
        self.hasKeyboard = true
    }
}

Objective-c相关问答推荐

导航回上一个视图控制器

我在哪里可以找到 info.plist 文件?

Objective C 中的多个委托

Objective-C,如何获取 UTC 时区的当前日期?

在 ARC 之后,我应该为调度队列使用什么属性?

NSArray 添加元素

如何与 UITableView 一起滚动标题?

从我在 iPhone 上的应用程序调用官方 *Settings* 应用程序

iOS 7 状态栏与 NavigationBar 冲突

如何判断特定的 ViewController 视图当前是否可见?

在Objective-C中替换字符串中的一个字符

如何删除手势识别器

如何推送两个视图控制器但只为第二个设置动画过渡?

如何在 Objective-C (iOS) 中判断 NaN 值

NSHTTPCookieStorage 状态未在应用退出时保存.那里有任何明确的知识/文档吗?

IOS 中的圆形进度条

为什么 detailTextLabel 不可见?

如何在 Cocoa 中获取当前日期

为什么 Select Emacs/Vim/Textmate? Xcode 还不够好吗?

iPhone - dequeueReusableCellWithIdentifier 用法