1. Когда клавиатура появляется на экране в приложение "прилетает" нотификация
UIKeyboardWillShowNotification. Когда клавиатура пропадает с экрана -
UIKeyboardWillHideNotification соответственно.
В контроллере, где необходимо каким-либо образом реагировать на это поведение необходимо подписаться на эти нотификации (например в
viewDidLoad):
- (void) registerNotification {
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
[nc addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
[nc addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
}
2. Рассмотрим возможную реакцию на появление клавиатуры:
- (void) keyboardWillShow: (NSNotification *) notification {
NSValue *value = [notification.userInfo objectForKey: UIKeyboardFrameEndUserInfoKey];
CGRect keyEndFrame = [value CGRectValue];
CGRect keyFrame = [self.view convertRect:keyEndFrame toView:nil];
NSNumber *duration = [notification.userInfo objectForKey: UIKeyboardAnimationDurationUserInfoKey];
[self showKeyBoardWithKeyFrame:keyFrame andDuration:[duration doubleValue]];
}
Вместе с нотификацией приходит много полезной информации о поведении клавиатуры в ближайшее время: ее размер, время анимации и даже поведение во время анимации (с затуханием или с разгоном).
В приведенном коде мы берем финальный фрейм (
keyEndFrame) в виде NSValue и преобразуем его в систему координат контроллера.
Кроме того получаем длительность анимации (
duration).
3. Реакция на появление
Предположим, что все наши элементы лежат в UIScrollView (
_scrollView) и она занимает всю область экрана.
Тогда нам достаточно лишь сдвинуть ее фрейм, что бы все элементы имели возможность быть показанными на экране.
- (void) showKeyBoardWithKeyFrame:(CGRect)keyFrame andDuration:(NSTimeInterval) duration {
BOOL animation = (duration > 0.0) ? YES : NO;
CGFloat keyboardHeight = keyFrame.size.height;
CGFloat scrollHeight = self.view.bounds.size.height - keyboardHeight;
CGRect scrollFrame = _scrollView.frame;
scrollFrame.size.height = scrollHeight;
if (animation) {
[UIView animateWithDuration:duration delay:0.0 options:UIViewAnimationOptionBeginFromCurrentState animations:^{
[_scrollView setFrame: scrollFrame];
} completion:nil];
} else {
[_scrollView setFrame: scrollFrame];
}
}