Высота клавиатуры iOS неверно указана на UIKeyboardWillShowNotification/

Я пытаюсь прокрутить свой текст до появления клавиатуры. Я стараюсь следовать собственному руководству Apple по адресу https://developer.apple.com/library/ios/documentation/StringsTextFonts/Conceptual/TextAndWebiPhoneOS/KeyboardManagement/KeyboardManagement.html. Вместо просмотра прокрутки и кадров я использую автозапуск, но общая идея такая же (подписка на уведомления о клавиатуре и анимация ограничений макета соответственно). Однако, когда я показываю клавиатуру, между текстовым видом и клавиатурой есть пробел: (это скриншот с турецкой клавиатуры, но тот же самый пробел, отмеченный красным, присутствует во всех установленных клавиатурах, включая пользовательские). (Снимок экрана с iPhone 6 Plus, но проблема также присутствует и на других размерах экрана)

enter image description here

Я видел, что не может получить правильное значение высоты клавиатуры в iOS8, и я попытался использовать как UIKeyboardFrameEndUserInfoKey, так и UIKeyboardFrameBeginUserInfoKey, но все они в том же промежутке. Я попытался установить UIKeyboardWillShowNotification и на UIKeyboardDidShowNotification, но все же у меня такой же разрыв. Я думаю, что разрыв связан с предложениями на некоторых клавиатурах на 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;

UPDATE, VOL 2: Я также видел iOS 8 Изменение ориентации: рамка клавиатуры отображается неправильно, но я испытываю проблема также в iPhone 5s iOS 7.1 Simulator, поэтому это не проблема с iOS 8. Как я могу решить эту проблему? Я определенно не хочу жестко кодировать значения высоты клавиатуры в мире iOS 8.

UPDATE, VOL 3: Я также попробовал его с английской клавиатурой с предложениями как вкл, так и выключить. Он по-прежнему появляется в отношении общего размера клавиатуры, поэтому он не касается представления предложений/автозаполнения:

enter image description hereenter image description here

Ответ 1

Может быть, вы используете контроллер панели вкладок, если да, тогда, когда маркер u отобразит представление после того, как была показана клавиатура, вычислите нижнюю границу поля без высоты панели вкладок.

Вы можете найти высоту панели вкладок, используя:

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;