IOS 8 UIView не двигается вверх, когда появляется клавиатура

Я разрабатываю приложение для чата с UITableView и UIView, содержащими в нем UITextField и UIButton. Я использую следующий код для перемещения UIView вверх при появлении клавиатуры.

(void)keyboardWillShow:(NSNotification *)notification
{

    NSDictionary* info = [notification userInfo];
    CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;

    [UIView animateWithDuration:0.2f animations:^{

        CGRect frame = self.inputView.frame;
       UIInterfaceOrientation orientation = self.interfaceOrientation;
    if (orientation == UIInterfaceOrientationLandscapeLeft || orientation ==        UIInterfaceOrientationLandscapeRight)
            frame.origin.y -= kbSize.width;
        else
            frame.origin.y -= kbSize.height;

        self.inputView.frame = frame;
       ;
    }];
}

Этот код работает нормально до iOS 7, но в iOS 8 UIView не отображается над клавиатурой.

Кто-нибудь может спросить, что может быть возможной проблемой, или есть что-то, что изменилось в iOS 8?

Ответ 1

Ваш код кажется правильным, но я предпочту использовать UIKeyboardDidChangeFrameNotification или UIKeyboardWillChangeFrameNotification, потому что они расскажут вам об изменении рамки клавиатуры, когда предиктивная строка текста поднимается или опускается, когда клавиатура находится в поле зрения.

В ViewDidLoad добавьте этот

[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(keyboardFrameDidChange:)
                                             name:UIKeyboardDidChangeFrameNotification object:nil];

а затем вставьте этот метод в свой ViewController

-(void)keyboardFrameDidChange:(NSNotification*)notification{
    NSDictionary* info = [notification userInfo];

    CGRect kKeyBoardFrame = [[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
    [yourView setFrame:CGRectMake(0, kKeyBoardFrame.origin.y-yourView.frame.size.height, 320, yourView.frame.size.height)];
}

Это будет работать со всеми вашими клавиатурными случаями, например, когда оно вверх или вниз или изменяется в его кадре с помощью предиктивной текстовой строки

а также удалить наблюдателя, когда вы покидаете свой просмотр

Ответ 2

Принятый ответ почти прав. Чтобы соответствовать анимации вашего представления с клавиатурой, вы хотите использовать UIKeyboardWillChangeFrameNotification, а не UIKeyboardDidChangeFrameNotification. Таким образом, анимация, которую вы запускаете, будет точно соответствовать настройке клавиатуры. Вот несколько кодов, чтобы сделать всю вещь. Я использую анимацию клавиатуры для анимации констант ограничения автоопределения, но вы можете легко адаптировать ее для анимации всего кадра представления. (Обратите внимание, что мы должны использовать анимацию старого стиля школы, чтобы подключиться к UIKeyboardCurveInfoKey, которая обеспечивает кривую анимации, точно соответствующую анимации клавиатуры.

В режиме просмотраDidLoad:

[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(keyboardFrameDidChange:)
                                             name:UIKeyboardWillChangeFrameNotification
                                           object:nil];

В ViewController:

- (void)keyboardFrameDidChange:(NSNotification *)notification {
    NSDictionary *info = [notification userInfo];

    CGRect kKeyBoardFrame = [[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
    CGFloat height = kKeyBoardFrame.size.height; 
    [self.view removeConstraints:self.verticalButtonConstraints];
    NSDictionary *metrics = @{@"height" : @(height)};
    NSDictionary *views = @{@"nextButton" : self.nextButton};

    self.verticalButtonConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:  [nextButton(52)]-(height)-|" options:0 metrics:metrics views:views];
    [self.view addConstraints:self.verticalButtonConstraints];

    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:[notification.userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue]];
    [UIView setAnimationCurve:[notification.userInfo[UIKeyboardAnimationCurveUserInfoKey] integerValue]];
    [UIView setAnimationBeginsFromCurrentState:YES];
    [self.view layoutIfNeeded];
   [UIView commitAnimations];

}

Ответ 3

Я просто столкнулся с этим и сделал открытие, которое, как я думал, поделюсь. В макетах iOS 8 макеты для основного представления будут выполняться всякий раз, когда клавиатура собирается или собирается исчезнуть. Эти проходы не выполняются на iOS 7. Итак, если вы попытаетесь анимировать под-представление основного вида в keyBoardWillShow или keyboardWillChangeFrame, анимация будет отменена с помощью прохода макета, и ваши подпункты, которые вы пытались оживить, вернутся к их оригинальная позиция. Вот почему keyboardDidChangeFrame работает, чтобы анимировать subviews и keyboardWillChangeFrame.

Что-то странное, я также отметил время, когда эти вызовы сделаны. Кажется, что в первый раз, когда клавиатура появляется после запуска приложения, вызов клавиатурыDidChangeFrame происходит слишком поздно, чтобы быть в состоянии оживить клавиатуру, чтобы они скользнули вместе, но во второй и последующие времена, на которые показывает клавиатура, вызов клавиатурыDidChangeFrame происходит раньше, и кажется, что вы действительно можете анимировать представления вместе с клавиатурой.

Я должен отметить, что я использую С# и Xamarin в качестве платформы разработки для iOS, поэтому при использовании Swift или Obj-C это может быть другим.

Ответ 4

Вы можете использовать аксессуар, который будет прикреплен к верхней части клавиатуры. В качестве альтернативы, если вам нужно больше полномочий по настройке, вы можете использовать уведомления, как описано @pankaj_wadwha, для получения информации о кадре. Бонус: вы также можете получить информацию о анимации (например, скорость), чтобы ваш взгляд отлично перемещался по клавиатуре.