Держать объект поверх клавиатуры в случае становленияFirstResponder или resignFirstResponder? - PullRequest
13 голосов
/ 02 января 2012

У меня в настоящее время UITextField поверх клавиатуры.Когда вы нажимаете на нее, она должна прилипать к клавиатуре и плавно двигаться вверх.Я не знаю точную продолжительность и тип анимации клавиатуры, поэтому она действительно неровная.Вот что у меня есть:

[theTextView resignFirstResponder];
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDelegate:self];
[UIView setAnimationDuration:0.25];
[UIView setAnimationCurve:UIViewAnimationCurveLinear];
// Frame changes go here (move down 216px)
[UIView commitAnimations];

[theTextView becomeFirstResponder];
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDelegate:self];
[UIView setAnimationDuration:0.25];
[UIView setAnimationCurve:UIViewAnimationCurveLinear];
// Frame changes go here (move up 216px)
[UIView commitAnimations];

Если кто-то делал что-то подобное раньше, я хотел бы знать настройки, которые вы использовали для плавной анимации, и чтобы казалось, что полоса «прилипла» кверхняя часть клавиатуры.

Ответы [ 4 ]

45 голосов
/ 02 января 2012

UIKit отправляет UIKeyboardWillShowNotification, когда показывает клавиатуру, и UIKeyboardWillHideNotification, когда скрывает клавиатуру.Эти уведомления содержат все, что вам нужно для правильной анимации вашего UITextField.

Допустим, ваш UITextField находится в свойстве под названием myTextField.

Сначала вам нужно зарегистрироваться дляуведомления где-то.То, где вы регистрируетесь, зависит от того, какой объект отвечает за перемещение myTextField.В моем проекте ответственным является супервизор поля, и поскольку я загружаю свой пользовательский интерфейс из пера, я делаю это в суперпредставлении awakeFromNib:

- (void)awakeFromNib
{
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHideOrShow:) name:UIKeyboardWillHideNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHideOrShow:) name:UIKeyboardWillShowNotification object:nil];
}

Если вы используете UIViewController для перемещения полявы, вероятно, захотите сделать это в viewWillAppear:animated:.

Вы должны отменить регистрацию в вашем dealloc или viewWillDisappear:animated::

- (void)dealloc
{
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

Конечно, хитрый бит вметод keyboardWillHideOrShow:.Сначала я извлекаю параметры анимации из уведомления:

- (void)keyboardWillHideOrShow:(NSNotification *)note
{
    NSDictionary *userInfo = note.userInfo;
    NSTimeInterval duration = [[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
    UIViewAnimationCurve curve = [[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] intValue];

    CGRect keyboardFrame = [[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];

keyboardFrame находится в глобальной системе координат.Мне нужно преобразовать кадр в ту же систему координат, что и myTextField.frame, а myTextField.frame находится в системе координат myTextField.superview:

    CGRect keyboardFrameForTextField = [self.myTextField.superview convertRect:keyboardFrame fromView:nil];

Далее я вычисляю нужный кадр myTextField перейти к.Нижний край нового кадра должен быть равен верхнему краю кадра клавиатуры:

    CGRect newTextFieldFrame = self.myTextField.frame;
    newTextFieldFrame.origin.y = keyboardFrameForTextField.origin.y - newTextFieldFrame.size.height;

Наконец, я анимирую myTextField к его новому кадру, используя те же параметры анимации, что и клавиатура:

    [UIView animateWithDuration:duration delay:0 options:UIViewAnimationOptionBeginFromCurrentState | curve animations:^{
        self.myTextField.frame = newTextFieldFrame;
    } completion:nil];
}

Здесь все собрано вместе:

- (void)keyboardWillHideOrShow:(NSNotification *)note
{
    NSDictionary *userInfo = note.userInfo;
    NSTimeInterval duration = [[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
    UIViewAnimationCurve curve = [[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] intValue];

    CGRect keyboardFrame = [[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
    CGRect keyboardFrameForTextField = [self.myTextField.superview convertRect:keyboardFrame fromView:nil];

    CGRect newTextFieldFrame = self.myTextField.frame;
    newTextFieldFrame.origin.y = keyboardFrameForTextField.origin.y - newTextFieldFrame.size.height;

    [UIView animateWithDuration:duration delay:0 options:UIViewAnimationOptionBeginFromCurrentState | curve animations:^{
        self.myTextField.frame = newTextFieldFrame;
    } completion:nil];
}
5 голосов
/ 02 января 2012

Установите текстовое поле (или представление, содержащее текстовое поле) как inputAccessoryView поля, которое вы редактируете. Затем он будет автоматически прикреплен к верхней части клавиатуры и соответствующим образом анимирован.

0 голосов
/ 19 июля 2018

Используйте этот код в уведомлении клавиатуры:

@objc func keyboardWillShowNotification(notification: Notification) {
    let keyboardHeight = (notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue.size.height ?? 216
    let duration = notification.userInfo?[UIKeyboardAnimationDurationUserInfoKey] as? Double ?? 0.25
    let curve = (notification.userInfo?[UIKeyboardAnimationCurveUserInfoKey] as? UInt ?? 7) << 16
    tableViewBottomConstraint.constant = keyboardHeight - submitButtonContainer.frame.size.height

    UIView.animate(withDuration: duration, delay: 0, options: [UIViewAnimationOptions(rawValue: curve)], animations: {
        // Animation
    }, completion: nil)
}
0 голосов
/ 02 января 2012

для того, чтобы UITextField пристыковался к клавиатуре (с анимацией), необходимо выполнить вычисления смещения и применить изменения смещения к представлению прокрутки (при условии, что UITextField помещен в UIScrollView) с использованием метода setContentOffset:animation:.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...