Держать объект поверх клавиатуры в случае становления FirstResponder или resignFirstResponder?
В настоящее время у меня есть 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 ответа
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];
}
Установите текстовое поле (или представление, содержащее текстовое поле) как inputAccessoryView
поля, которое вы редактируете. Затем он будет автоматически прикреплен к верхней части клавиатуры и соответствующим образом анимирован.
Для того, чтобы UITextField пристыковался к клавиатуре (с анимацией), необходимо выполнить вычисления смещения и применить изменения смещения к представлению прокрутки (при условии, что UITextField помещен в UIScrollView) с помощью setContentOffset:animation:
метод.
Используйте этот код в уведомлении клавиатуры:
@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)
}