【问题标题】:iOS keyboard height returned incorrectly on UIKeyboardWillShowNotification/iOS 键盘高度在 UIKeyboardWillShowNotification/ 上返回不正确
【发布时间】:2015-01-04 12:59:55
【问题描述】:

我试图在键盘出现时向上滚动我的文本视图。我正在尝试在https://developer.apple.com/library/ios/documentation/StringsTextFonts/Conceptual/TextAndWebiPhoneOS/KeyboardManagement/KeyboardManagement.html 上遵循 Apple 自己的教程。我使用的是自动布局而不是滚动视图和框架,但总体思路是相同的(订阅键盘通知,并相应地为布局约束设置动画)。但是,当我显示键盘时,文本视图和键盘之间存在间隙:(这是土耳其语键盘的屏幕截图,但在所有安装的键盘中都存在相同的间隙,用红色标记,包括自定义键盘)。 (iPhone 6 Plus 的屏幕截图,但其他屏幕尺寸也存在此问题)

我见过can't get correct value of keyboard height in iOS8,并且我尝试过同时使用UIKeyboardFrameEndUserInfoKeyUIKeyboardFrameBeginUserInfoKey,但它们都会导致相同的差距。我已经尝试附加UIKeyboardWillShowNotificationUIKeyboardDidShowNotification,但仍然存在相同的差距。我认为这个差距与 iOS 8 上某些键盘的建议有关,但是当建议不存在时,它不应该报告带有建议的键盘大小。

这是我的代码:

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    [self registerForKeyboardNotifications];
}

- (void)registerForKeyboardNotifications
{
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(keyboardWillBeShown:)
                                                 name:UIKeyboardWillShowNotification object:nil];

    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(keyboardWillBeHidden:)
                                                 name:UIKeyboardWillHideNotification object:nil];

}

// Called when the UIKeyboardDidShowNotification is sent.
- (void)keyboardWillBeShown:(NSNotification*)aNotification
{
    NSDictionary* info = [aNotification userInfo];
    CGRect kb = [[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];

    float height = kb.size.height;
    sendZoneBottomConstraint.constant = height;
    [UIView animateWithDuration:.2 animations:^{
        [self.view layoutIfNeeded];
    }];
}

// Called when the UIKeyboardWillHideNotification is sent
- (void)keyboardWillBeHidden:(NSNotification*)aNotification
{
    sendZoneBottomConstraint.constant = 0;
    [UIView animateWithDuration:.2 animations:^{
        [self.view layoutIfNeeded];
    }];
}

sendZoneBottomConstraint 是最底部视图到底部布局指南的底部间距。

更新:我尝试将键盘矩形从窗口坐标更改为我的视图坐标,但没有任何改变。这是我尝试过的:

CGRect kb = [[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
kb = [self.view.window convertRect:kb toView:self.view];
float height = kb.size.height;

更新,第 2 卷:我也看到了 iOS 8 Orientation change: Keyboard frame does not display correctly,但我在 iPhone 5s iOS 7.1 模拟器上也遇到了这个问题,所以这不仅仅是 iOS 8 的问题。 我怎么解决这个问题?我绝对不想在 iOS 8 世界中硬编码任何键盘高度值。

更新,第 3 卷:我也尝试过使用英文键盘,并打开和关闭建议。它仍然相对于键盘的总大小出现,因此与建议/自动完成视图无关:

【问题讨论】:

  • 您是否将键盘的框架转换为适当的本地视图坐标?使用您遇到问题的一些相关代码更新您的问题。
  • @rmaddy 我已经包含了代码。如何将键盘的框架转换为本地视图坐标?我的意思是我知道我会使用 convertRect:[to|from]View: 但从 which 视图到我本地视图的坐标?
  • @CanPoyrazoğlu:我通常从 self.window 转换。
  • @rmaddy 更改坐标并没有改变任何东西,请参阅我更新的问题。
  • 在我看来,您对选项卡视图控制器中的底部布局指南有一个布局约束。如果是这样,考虑一下,解决方案很简单。

标签: ios ios8


【解决方案1】:

也许你正在使用标签栏控制器,如果是,那么当你在显示键盘后对视图进行边距时,计算没有标签栏高度的边距底部。

您可以使用以下方法找到标签栏高度:

self.tabBarController?.tabBar.frame.height

【讨论】:

  • 谢谢,我有同样的问题,这是答案
  • 就是这样!谢谢。
【解决方案2】:

对于强大的键盘高度计算,您可以使用以下方法:

注意:我从 IQKeyboard 借用了一些逻辑来实现这个解决方案。

CGRect kbFrame = [[aNotification userInfo][UIKeyboardFrameEndUserInfoKey] CGRectValue];

CGRect screenSize = [[UIScreen mainScreen] bounds];

CGRect intersectRect = CGRectIntersection(kbFrame, screenSize);//Calculating actual keyboard displayed size, keyboard frame may be different when hardware keyboard is attached (Bug ID: #469) (Bug ID: #381)

CGSize kbSize;
if (CGRectIsNull(intersectRect)) {
    kbSize = CGSizeMake(screenSize.size.width, 0);
} else {
    kbSize = intersectRect.size;
}

//

UIViewController *rootViewController = [UIApplication sharedApplication].keyWindow.rootViewController;
while (rootViewController) {
    if ([rootViewController isKindOfClass:[UINavigationController class]]) {
        UINavigationController *navigationController = (UINavigationController *)rootViewController;
        UIViewController *nextRootViewController = [[navigationController viewControllers] lastObject];
        if (nextRootViewController) {
            rootViewController = nextRootViewController;
            continue;
        } else {
            break;
        }
    }
    if ([rootViewController isKindOfClass:[UITabBarController class]]) {
        UITabBarController *tabBarController = (UITabBarController *)rootViewController;
        UIViewController *nextRootViewController = tabBarController.selectedViewController;
        if (nextRootViewController) {
            rootViewController = nextRootViewController;
            continue;
        } else {
            break;
        }
    }
    if (!rootViewController.presentedViewController) {
        break;
    }
    rootViewController = (UIViewController *)rootViewController.presentedViewController;
}

//

CGFloat navigationBarAreaHeight = [[UIApplication sharedApplication] statusBarFrame].size.height + rootViewController.navigationController.navigationBar.frame.size.height;
CGFloat layoutAreaHeight = rootViewController.view.layoutMargins.top;

CGFloat topLayoutGuide = MAX(navigationBarAreaHeight, layoutAreaHeight);

CGFloat bottomLayoutGuide = rootViewController.view.layoutMargins.bottom;

float magicNumber = 5;//Apple Constant

//

float keyboardHeight = kbSize.height-topLayoutGuide-bottomLayoutGuide+magicNumber;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-10-12
    • 1970-01-01
    • 2018-01-23
    • 2018-05-17
    • 2015-03-05
    • 1970-01-01
    • 2016-07-08
    • 2015-11-14
    相关资源
    最近更新 更多