9

我正在创建一个类似于 iPad 的 iMessage 应用程序的应用程序,它可以发送消息。因此,当显示键盘时,消息视图和输入附件视图的底部有一个输入视图。此外,当键盘在停靠或未停靠时显示时,必须正确调整消息视图的大小。

我遇到的问题是来自 UIKeyboardWillChangeFrameNotification 的通知数据不一致。

首先,用户可以通过 3 种方式取消键盘连接:

  1. 按住右下键,然后向上滑动
  2. 长按右下键,弹出菜单时选择“取消停靠”
  3. 长按右下键,弹出菜单时选择“拆分”

对于案例 #1,来自 UIKeyboardWillChangeFrameNotification 的通知数据是一致的。这是数据:

userInfo = {
    UIKeyboardFrameBeginUserInfoKey = "NSRect: {{0, 0}, {768, 304}}";
}

对于案例 #2 和 #3,数据不一致,这是我收到的:

userInfo = {
    UIKeyboardAnimationCurveUserInfoKey = 0;
    UIKeyboardAnimationDurationUserInfoKey = "0.25";
    UIKeyboardBoundsUserInfoKey = "NSRect: {{0, 0}, {768, 304}}";
    UIKeyboardCenterBeginUserInfoKey = "NSPoint: {384, 872}";
    UIKeyboardCenterEndUserInfoKey = "NSPoint: {384, 1136}";
    UIKeyboardFrameBeginUserInfoKey = "NSRect: {{0, 0}, {768, 304}}";
    UIKeyboardFrameChangedByUserInteraction = 0;
    UIKeyboardFrameEndUserInfoKey = "NSRect: {{0, -264}, {768, 304}}";
}

奇怪的是,当我在案例 #2 或 #3 下监听 UIKeyboardDidChangeFrameNotification 时,数据按预期输入:

userInfo = {
    UIKeyboardFrameBeginUserInfoKey = "NSRect: {{0, 0}, {768, 304}}";
}

为什么通知数据不同?有没有人找到一种明确的方法来检测拆分键盘事件?

4

2 回答 2

3

没有明确的方法没有。

我在接下来的步骤中解决了这个问题:

  1. 获取当前方向。
  2. 如果方向是横向,那么我得到UIKeyboardFrameEndUserInfoKey 的高度。必须等于216。表示键盘是Split mode,否则不是;
  3. 如果方向是纵向,那么我得到UIKeyboardFrameEndUserInfoKey 的高度。必须等于216。表示键盘是Split mode,否则不是;

例如,我更新了我的要点。使用 convertRect 方法。

于 2013-07-10T09:35:32.850 回答
1

这是确定键盘是否拆分的一种有点笨拙但可靠的方法。

NSArray *classPath = @[
  @"KeyboardAutomatic",
  @"KeyboardImpl",
  @"KeyboardLayoutStar",
  @"KBKeyplaneView",
  @"KBSplitImageView"
];
UIView *splitView = textField.inputAccessoryView.superview;
for (NSString *className in classPath) {
  for (UIView *subview in splitView.subviews) {
    if ([NSStringFromClass([subview class]) rangeOfString:className].location != NSNotFound) {
      splitView = subview;
      break;
    }
  }
}
BOOL isSplit = [splitView.subviews count] > 1;

显然,为了让它工作,你需要一个非零的 UITextField/UITextView inputAccessoryView(你可以只使用一个空视图)。

注意:的行为textField.inputAccessoryView.superview非常挑剔,通常取决于在调用 之前已经显示过一次键盘superview。此外,为了通过 App Store 提交过程,我从私有类名中删除了“UI”前缀。这并不能保证 Apple 不会标记您的应用程序,但这种方法以前已经成功使用过。

我只在 iOS7 上测试过它,但如果它在其他版本的 iOS 上不起作用,可以使用类似的方法。

于 2014-03-15T00:09:51.260 回答