iPhone - 当键盘已显示时如何知道其大小

9

好的,我知道可以使用通知UIKeyboardWillShowNotification读取键盘的大小,以及这个

keybSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;

但这只有在键盘显示时才可用。
但问题是:我有一个窗口,必须在键盘可见和iPhone旋转时调整自己的位置。当我旋转iPhone时,两个委托方法willRotateToInterfaceOrientation和didRotateFromInterfaceOrientation都会运行并处理旋转。在这些方法内部,我需要知道当前键盘的高度,以便正确定位视图。问题是,由UIKeyboardWillShowNotification通知触发的方法在委托方法处理旋转后运行。
方法运行的顺序是:
1. willRotateToInterfaceOrientation 2. didRotateFromInterfaceOrientation 3. UIKeyboardWillShowNotification方法
换句话说,键盘高度只是在最后读取,这意味着方法1和2都将使用旧的键盘高度。
我的问题是:是否有一种直接读取可见键盘高度而不依赖于通知触发的方法的方法?
谢谢

你可以将这些值硬编码到你的应用程序中。据我所知,所有iOS设备的键盘高度都是相同的。 - ryyst
1
@ryyst:不一定。不同的语言/本地化可能需要不同大小的键盘。 - Cameron Spickert
@Cameron Spickert:你确定吗?我从未见过大小不同的键盘... - ryyst
1
@ryyst:即使没有不同尺寸的键盘,苹果也不保证SDK中的键盘大小不会改变,这意味着他们未来可能会更改它,从而破坏硬编码的应用程序。 - Cameron Spickert
@Cameron Spickert:虽然这很不可能。另外,为什么自动调整大小不能解决问题? - ryyst
你找到任何解决方案了吗?我也有完全相同的问题,特别是在iOS 5上,一些键盘比普通键盘高。 - nonamelive
2个回答

4

变体1

您可以使用此代码片段来探索视图层次结构:

- (void)printSubviews:(UIView *)aView {
    NSLog(@"%@ - %@", [aView class], NSStringFromCGRect([aView frame]));
    for (UIView *view in [aView subviews]) {
        [self printSubviews:view];
    }
}


- (void)printAllViews {
    for (UIWindow *window in [[UIApplication sharedApplication] windows]) {
        [self printSubviews:window];
    }
}

你会发现从你得到的值很容易推算出键盘的大小。
变体2
或者,你可以导入UIKeyboard.h(可以在互联网上找到)。它包括了一个方法来获取各种界面方向的默认键盘大小。然而,这将使用私有API,所以你可能要小心处理。

-1

我在旋转时键盘已经可见的情况下,设置UIScrollView的内容插入有问题。这是我的解决方案(它不涉及任何太过hacky的解决方案)。

你的视图控制器订阅UIKeyboardWillShowNotification的想法是正确的,也是最好的方法 - 不要尝试以其他方式计算键盘大小,因为a)键盘大小可能是不可预测的,b)您不想冒使用私有API的风险。

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    [[NSNotificationCenter defaultCenter] addObserver:self 
                                          selector:@selector(keyboardWillShow:)
                                          name:UIKeyboardWillShowNotification
                                          object:nil];
}

这是 keyboardWillShow 方法。如果你正在使用 UIKeyboardWillShowNotification (就像我一样),你会想要从 UIKeyboardFrameEndUserInfoKey 键中获取结果键盘的大小。
- (void)keyboardWillShow:(NSNotification *)notification {

    NSDictionary *info = [notification userInfo];
    NSTimeInterval duration = [[info objectForKey:UIKeyboardAnimationDurationUserInfoKey]
                               doubleValue];
    CGSize keyboardSize = [[info objectForKey:UIKeyboardFrameEndUserInfoKey] 
                           CGRectValue].size;

    UIInterfaceOrientation orientation = [[UIApplication sharedApplication]
                                          statusBarOrientation];
    UIEdgeInsets insets = UIEdgeInsetsMake(0, 0, keyboardSize.height, 0);

    // The gotcha is that the keyboard size as reported by
    // UIKeyboardFrameEndUserInfoKey is always reported as if the device was in
    // portrait mode. I've had to work around  that a little by setting the
    // bottom edge to the keyboard's width.
    if (UIInterfaceOrientationIsLandscape(orientation)) {
        insets = UIEdgeInsetsMake(0, 0, keyboardSize.width, 0);
    }

    [UIView animateWithDuration:duration
                          delay:0
                        options:UIViewAnimationOptionCurveEaseInOut
                     animations:^{
        self.gridScrollView.contentInset = insets;
        self.gridScrollView.scrollIndicatorInsets = insets;
    } completion:nil];
}

希望这可以帮助你 — 再次强调,使用通知实现你想要的功能是完全可行和安全的。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接