Разработка iPhone/iPod touch приложений: Полезности – UIToolBar над UIKeyboard
Много кто видел как в некоторых приложениях вместе с клавиатурой выезжает UIToolBar – примерно так, как это показано на рисунке.
Есть несколько вариантов так сделать. Первый, и самый “простой” – это позиционировать UIToolBar в нужное место до/или после того, как началось редактирование, и клавиатура должна выехать. Даже для начинающего программиста эта задача не составит особого труда.
Программист более продвинутый, который любит и умеет читать документацию или искать, без особого труда найдет , что можно подписаться на глобальные события UIKeyboardWillShowNotification и UIKeyboardWillHideNotification, чтобы вовремя подставлять/убирать UIToolBar.
После того, как нам не понравится (а нам не понравится) то, что UIToolBar “прыгает” вместо того, чтобы плавно уезжать вместе с клавиатурой, добавим немного анимации. После таких манипуляций должен получиться примерно следующий код:
// Здесб у нас будут "константы"
#define VIEWPORT_SIZE 320
#define KEYBOARD_HEIGHT 215
#define TOOLBAR_HEIGHT 44
#define KEYBOARD_TRANSITION_DURATION 0.3
// Подписываемся на глобальные события
- (void)viewDidLoad {
[super viewDidLoad];
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
// Событие перед появлением клавиатуры
[nc addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
// Событие перед скрытием клавиатуры
[nc addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
}
-(void) keyboardWillShow:(NSNotification *) note {
// Так как клавиатура появляется с самого низа экрана,
// то UIToolBar должен быть чуть-чуть выше
toolBar.frame = CGRectMake(0, [[self view] frame ].size.height - TOOLBAR_HEIGHT, VIEWPORT_SIZE, TOOLBAR_HEIGHT);
// Вычисляем точку, куда должен "прилететь" UIToolBar
CGRect toolBarRect = [toolBar frame];
toolBarRect.origin.y = [[self view] frame].size.height - KEYBOARD_HEIGHT - TOOLBAR_HEIGHT;
// Добавляем красивости
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:KEYBOARD_TRANSITION_DURATION];
[toolBar setFrame:toolBarRect];
[UIView commitAnimations];
}
-(void) keyboardWillHide:(NSNotification *) note {
//А вот "улетать" UIToolBar должен за пределы экрана.
//Он будет "улетать" чуть-чуть быстрее, чем клавиатура
//Выглядит неплохо, хоть и не совсем правильно.
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:KEYBOARD_TRANSITION_DURATION];
toolBar.frame = CGRectMake(0, [[self view] frame ].size.height, VIEWPORT_SIZE, TOOLBAR_HEIGHT);
[UIView commitAnimations];
}
Это, если использовать “константы”. Трудно себе представить, конечно, но что будет, если вдруг размер клавиатуры/время ее появляения/анимация ее появления вдруг изменятся? Как делать все правильно? Обращаю внимание, что в большинстве случаев вполне достаточно кода который уже был приведен, и я сам считаю, что “Що занадто – то нездраво”(“Что чересчур – то нездорово”). Но если все-таки надо, то вышеперечисленную информацию можно “достать” из NSNotification userInfo. userInfo – это, обычно, NSDictionary, который по ключам хранит полезную информацию:
//Тип анимации
// UIKeyboardAnimationCurveUserInfoKey = 0;
//Время анимации ("выезд клавиатуры")
// UIKeyboardAnimationDurationUserInfoKey = 0.300000011920929;
//Размеры клавиатуры
// UIKeyboardBoundsUserInfoKey = NSRect: {{0, 0}, {320, 216}};
//Центр клавиатуры в начале анимации
// UIKeyboardCenterBeginUserInfoKey = NSPoint: {160, 588};
//Центр клавиатуры в конце анимации
// UIKeyboardCenterEndUserInfoKey = NSPoint: {160, 372};
...
// А вот, собвственно, как віглядит код:
-(void) keyboardWillShow:(NSNotification *) note {
NSDictionary * userInfo = [note userInfo];
CGRect keyboardSize;
[[userInfo objectForKey:UIKeyboardBoundsUserInfoKey] getValue:&keyboardSize];
CGPoint keyboardCenterBeforeAnimation;
[[userInfo objectForKey:UIKeyboardCenterBeginUserInfoKey] getValue:&keyboardCenterBeforeAnimation];
CGPoint keyboardCenterAfterAnimation;
[[userInfo valueForKey:UIKeyboardCenterEndUserInfoKey] getValue:&keyboardCenterAfterAnimation];
double animationDuration;
[[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] getValue:&animationDuration];
int animationType;
[[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] getValue:&animationType];
toolBar.frame = CGRectMake(0, keyboardCenterBeforeAnimation.y - keyboardSize.size.height / 2 - TOOLBAR_HEIGHT, keyboardSize.size.width, TOOLBAR_HEIGHT);
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:animationDuration];
[UIView setAnimationCurve:animationType];
[toolBar setFrame:CGRectMake(0, keyboardCenterAfterAnimation.y - keyboardSize.size.height / 2 - TOOLBAR_HEIGHT, keyboardSize.size.width, TOOLBAR_HEIGHT)];
[UIView commitAnimations];
}
Теперь вы знаете своего врага в лицо – и вся информация о нем есть. Как использовать эту информацию – решать вам ;) Я дал лишь один из вариантов ее использования ;)
И не забывайте, что у клавиатуры и ее событий есть некоторые особенности.







Antivirus
в 18:45, 01.02.2010Очень интересная статья, давно искал манула, как писать под UIKeyboard. Автору респект.
olgerd
в 2:15, 12.03.2010спасибо, пригодилось)
зы: еще нужно незабывать отписываться от нотификейшинов, когда они тебе не нужны… например:
[[NSNotificationCenter defaultCenter] removeObserver:self];
иначе можно натолкнуться на мелкие неприятности :) на чем я и попался
Павел Тайкало
в 10:12, 12.03.2010Спасибо, подправлю ;)