IOS 7 - анимация клавиатуры
Я пытаюсь понять новую анимацию клавиатуры в iOS 7.0 на симуляторе iPhone 5. Я хочу изменить размер UITableView
при появлении клавиатуры, но я не могу получить нужные детали анимации.
Я использую информацию из объекта NSNotification
, когда клавиатура появляется или исчезает.
Вот мой журнал:
Move keyboard from {{0, 920}, {320, 216}} to {{0, 352}, {320, 216}}
with duration: 0.400000
and animation curve: 7
UIViewAnimationCurveEaseInOut = 0
UIViewAnimationCurveEaseIn = 1
UIViewAnimationCurveEaseOut = 2
UIViewAnimationCurveLinear = 3
Кривая анимации - неизвестное значение, что мне делать?
Ответы
Ответ 1
Теперь я нашел решение. Анимация начинается с точки {0, 920}
до {0, 352}
. Проблема заключалась в том, что объект UITableView
начинался с размера {160, 568}
, поэтому я изменил размер UITableView
на {160, 920}
до начала анимации.
Относительно неизвестной кривой анимации я просто установил параметр animationCurve << 16
, чтобы преобразовать его из кривой анимации вида в параметр анимации просмотра.
Значение не равно линейности, легкости, легкости и легкости в анимационной кривой.
Вот мой код:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(_keyboardWillShow:)
name:UIKeyboardWillShowNotification
object:nil];
и
- (void)keyboardWillShow:(NSNotification *)aNotification {
NSDictionary *userInfo = aNotification.userInfo;
//
// Get keyboard size.
NSValue *beginFrameValue = userInfo[UIKeyboardFrameBeginUserInfoKey];
CGRect keyboardBeginFrame = [self.view convertRect:beginFrameValue.CGRectValue fromView:nil];
NSValue *endFrameValue = userInfo[UIKeyboardFrameEndUserInfoKey];
CGRect keyboardEndFrame = [self.view convertRect:endFrameValue.CGRectValue fromView:nil];
//
// Get keyboard animation.
NSNumber *durationValue = userInfo[UIKeyboardAnimationDurationUserInfoKey];
NSTimeInterval animationDuration = durationValue.doubleValue;
NSNumber *curveValue = userInfo[UIKeyboardAnimationCurveUserInfoKey];
UIViewAnimationCurve animationCurve = curveValue.intValue;
//
// Create animation.
CGRect tableViewFrame = self.tableView.frame;
bTableViewFrame.size.height = (keyboardBeginFrame.origin.y - tableViewFrame.origin.y);
self.tableView.frame = tableViewFrame;
void (^animations)() = ^() {
CGRect tableViewFrame = self.tableView.frame;
tableViewFrame.size.height = (keyboardEndFrame.origin.y - tableViewFrame.origin.y);
self.tableView.frame = tableViewFrame;
};
//
// Begin animation.
[UIView animateWithDuration:animationDuration
delay:0.0
options:(animationCurve << 16)
animations:animations
completion:nil];
}
Ответ 2
В iOS 7 клавиатура использует новую, недокументированную анимационную кривую. Хотя некоторые отметили, что использование недокументированного значения для опции анимации, я предпочитаю использовать следующее:
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:[notification.userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue]];
[UIView setAnimationCurve:[notification.userInfo[UIKeyboardAnimationCurveUserInfoKey] integerValue]];
[UIView setAnimationBeginsFromCurrentState:YES];
// work
[UIView commitAnimations];
В то время как анимация на основе блоков является рекомендацией, кривая анимации, возвращаемая с уведомлением о клавиатуре, является UIViewAnimationCurve
, тогда как параметр, который вам нужно передать на анимацию на основе блоков, - это UIViewAnimationOptions
. Использование традиционных методов анимации UIView позволяет напрямую передавать значение. Самое главное, что это будет использовать новую кривую бездокументальной анимации (целочисленное значение 7) и заставить анимацию соответствовать клавиатуре. И он будет работать так же хорошо на iOS 6 и 7.
Ответ 3
Вы можете использовать блок animateWithDuration
и задать внутри него кривую. Он чист и работает хорошо.
UIViewAnimationCurve curve = [[notification.userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] integerValue];
double duration = [[notification.userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
[UIView animateWithDuration:duration
delay:0
options:UIViewAnimationOptionBeginFromCurrentState
animations:^{
[UIView setAnimationCurve:curve];
/* ANIMATION HERE */
// don't forget layoutIfNeeded if you use autolayout
}
completion:nil];
Счастливое кодирование!
UPDATE
Вы можете использовать простую категорию UIViewController, написанную мной https://github.com/Just-/UIViewController-KeyboardAnimation
Ответ 4
Используйте UIKeyboardWillChangeFrameNotification
вместо этого, потому что некоторые международные клавиатуры, такие как китайская клавиатура, меняют высоту во время использования. Также этот код дает правильную высоту для клавиатуры, даже в ландшафтном режиме. (Примечание: код ниже для Автоотключение)
//set your observer, in a method like viewDidLoad
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillChange:) name:UIKeyboardWillChangeFrameNotification object:nil];
- (void)keyboardWillChange:(NSNotification *)notification {
CGRect initialRect = [notification.userInfo[UIKeyboardFrameBeginUserInfoKey] CGRectValue];
CGFloat initialHeight = self.view.frame.size.height - [self.view convertRect:initialRect fromView:nil].origin.y;
CGRect keyboardRect = [notification.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
CGFloat newHeight = self.view.frame.size.height - [self.view convertRect:keyboardRect fromView:nil].origin.y;
//set your constraints here, based on initialHeight and newHeight, which are the heights of the keyboard before & after animation.
[self.contentView setNeedsUpdateConstraints];
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:[notification.userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue]];
[UIView setAnimationCurve:[notification.userInfo[UIKeyboardAnimationCurveUserInfoKey] integerValue]];
[UIView setAnimationBeginsFromCurrentState:YES];
[self.contentView layoutIfNeeded];
[UIView commitAnimations];
}
Ответ 5
Чтобы использовать ту же анимацию, что и клавиатура, вам нужно использовать недокументированную опцию Curve.
- (void)keyboardWillHide:(NSNotification *)notification {
NSDictionary *userInfo = [notification userInfo];
CGRect rect = [userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
NSTimeInterval animationDuration = [[userInfo valueForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
NSInteger curve = [[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] intValue] << 16;
[UIView animateWithDuration:animationDuration delay:0.0 options:curve animations:^{
} completion:nil];
}
Я обнаружил, что на самом деле метод animateWithDuration:delay:usingSpringWithDamping:initialSpringVelocity:options:animations:completion:
- это новый способ, который все анимации выполняются в iOS7 и iOS8. Вы просто делаете правильную продолжительность, демпфирование и скорость, и вы получите тот же эффект, но даже вы можете изменить скорость/время.
Ответ 6
Зарегистрируйтесь для уведомления:
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
Отвечайте путем анимации изменения в frame.origin.y представления.
- (void)keyboardWillShow:(NSNotification *)aNotification {
NSDictionary *userInfo = aNotification.userInfo;
NSValue *endFrameValue = userInfo[UIKeyboardFrameEndUserInfoKey];
CGRect keyboardEndFrame = [self.view convertRect:endFrameValue.CGRectValue fromView:nil];
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:[aNotification.userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue]];
[UIView setAnimationCurve:[aNotification.userInfo[UIKeyboardAnimationCurveUserInfoKey] integerValue]];
[UIView setAnimationBeginsFromCurrentState:YES];
CGRect searchButtonFrame = self.searchButton.frame;
searchButtonFrame.origin.y = (keyboardEndFrame.origin.y - searchButtonFrame.size.height);
self.searchButton.frame = searchButtonFrame;
[UIView commitAnimations];
}