iPad分体键盘

时间:2012-05-25 06:08:35

标签: objective-c ipad keyboard-events

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

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

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

  1. 按住右下方的键,然后向上滑动
  2. 按住右下方的键,弹出菜单时选择“取消停靠”
  3. 按住右下方的键,弹出菜单时选择“拆分”
  4. 对于案例#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}}";
    }
    

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

2 个答案:

答案 0 :(得分:3)

没有明确的方法没有。

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

  1. 获取当前方向。
  2. 如果orientation是Landscape,那么我会获得UIKeyboardFrameEndUserInfoKey的 height 。它必须等于216.这意味着键盘是分离模式,否则不是;
  3. 如果方向是纵向,那么我得到UIKeyboardFrameEndUserInfoKey的高度。它必须等于216.这意味着键盘是分离模式,否则不是;
  4. 我使用convertRect方法更新gist for example.

答案 1 :(得分: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;

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

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

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