Alinhar programaticamente uma barra de ferramentas na parte superior do teclado do iPhone

Em vários casos, quero adicionar uma barra de ferramentas à parte superior do teclado do iPhone (como no iPhone Safari, quando você navega em elementos de formulário, por exemplo).

Atualmente estou especificando o retângulo da barra de ferramentas com constantes, mas como outros elementos da interface estão em stream – barras de ferramentas e barras de navegação na parte superior da canvas – toda vez que fazemos uma pequena alteração na interface, a barra de ferramentas fica desalinhada.

Existe uma maneira de determinar programaticamente a posição do teclado em relação à exibição atual?

A partir do iOS 3.2, há uma nova maneira de obter esse efeito:

UITextFields e UITextViews têm uma propriedade inputAccessoryView , que você pode definir para qualquer exibição, que é automaticamente exibida acima e animada com o teclado.

Note que a view que você usa não deve estar na hierarquia de view em outro lugar, nem deveria ser adicionada a alguma superview, isso é feito para você.

Então, basicamente:

No método init:

 NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; [nc addObserver:self selector:@selector(keyboardWillShow:) name: UIKeyboardWillShowNotification object:nil]; [nc addObserver:self selector:@selector(keyboardWillHide:) name: UIKeyboardWillHideNotification object:nil]; 

E, em seguida, temos methods referidos acima para ajustar a posição da barra:

 -(void) keyboardWillShow:(NSNotification *) note { CGRect r = bar.frame, t; [[note.userInfo valueForKey:UIKeyboardBoundsUserInfoKey] getValue: &t]; r.origin.y -= t.size.height; bar.frame = r; } 

Poderia torná-lo bonito, animando a mudança de posição, envolvendo-o em

  [UIView beginAnimations:nil context:NULL]; [UIView setAnimationDuration:0.3]; //... [UIView commitAnimations]; 

Isso é baseado na resposta existente do tonklon – estou apenas adicionando um trecho de código que mostra uma barra de ferramentas preta semitransparente na parte superior do teclado, junto com um botão “concluído” à direita:

 UIToolbar *toolbar = [[[UIToolbar alloc] init] autorelease]; [toolbar setBarStyle:UIBarStyleBlackTranslucent]; [toolbar sizeToFit]; UIBarButtonItem *flexButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:self action:nil]; UIBarButtonItem *doneButton =[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(resignKeyboard)]; NSArray *itemsArray = [NSArray arrayWithObjects:flexButton, doneButton, nil]; [flexButton release]; [doneButton release]; [toolbar setItems:itemsArray]; [aTextField setInputAccessoryView:toolbar]; 

e o -resignKeyboard parece com:

 -(void)resignKeyboard { [aTextField resignFirstResponder]; } 

Espero que ajude alguém.

Se você se registrar para notifications do teclado, ou seja, UIKeyboardWillShowNotification UIKeyboardWillHideNotification , etc, a notificação recebida conterá os limites do teclado no userInfo dict ( UIKeyboardBoundsUserInfoKey ).

Veja a referência da class UIWindow .

Em 3.0 e acima, você pode obter a duração e a curva de userInfo dictionary userInfo das notifications.

por exemplo, para animar o tamanho da vista para abrir espaço para o teclado, registre-se no UIKeyboardWillShowNotification e faça algo como o seguinte:

 - (void)keyboardWillShow:(NSNotification *)notification { [UIView beginAnimations:nil context:NULL]; [UIView setAnimationCurve:[[[notification userInfo] objectForKey:UIKeyboardAnimationCurveUserInfoKey] intValue]]; [UIView setAnimationDuration:[[[notification userInfo] objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue]]; CGRect frame = self.view.frame; frame.size.height -= [[[notification userInfo] objectForKey:UIKeyboardBoundsUserInfoKey] CGRectValue].size.height; self.view.frame = frame; [UIView commitAnimations]; } 

Faça uma animação semelhante para UIKeyboardWillHideNotification .

Eu encontrei este link muito útil para entender a visão de input passo a passo.

vista acessória de input

Crie este método e chame-o no ViewWillLoad:

  - (void) keyboardToolbarSetup { if(self.keyboardToolbar==nil) { self.keyboardToolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, 44)]; UIBarButtonItem *cancelButton = [[UIBarButtonItem alloc] initWithTitle:@"Cancel" style:UIBarButtonItemStylePlain target:self action:@selector(anyAction)]; UIBarButtonItem *extraSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil]; UIBarButtonItem *doneButton = [[UIBarButtonItem alloc] initWithTitle:@"Done" style:UIBarButtonItemStyleDone target:self action:@selector(anyOtherAction)]; NSArray *toolbarButtons = [[NSArray alloc]initWithObjects:cancelButton,extraSpace,doneButton, nil]; [self.keyboardToolbar setItems:toolbarButtons]; self.myTextView.inputAccessoryView=self.keyboardToolbar; } } 

Não há como (AFAIK) obter as dimensões da visualização do teclado. No entanto, é constante, pelo menos em todas as versões do iPhone até agora.

Se você calcular a posição da barra de ferramentas como um deslocamento da PARTE INFERIOR da sua visualização e levar em conta o tamanho da sua visualização, não deverá se preocupar se uma barra de navegação está presente ou não.

Por exemplo

 #define KEYBOARD_HEIGHT 240 // example - can't remember the exact size #define TOOLBAR_HEIGHT 30 toolBarRect.origin.y = viewRect.size.height - KEYBOARD_HEIGHT - TOOLBAR_HEIGHT; // move toolbar either directly or with an animation 

Em vez de definir, você pode criar facilmente uma function keyboardHeight que retorna o tamanho com base no fato de o teclado estar sendo exibido e mover o posicionamento da barra de ferramentas para uma function separada que reorganize seu layout.

Também pode depender de onde você faz este posicionamento, pois é possível que o tamanho da sua visualização possa mudar entre ser carregado e mostrado com base na configuração da sua barra de navegação. Eu acredito que o melhor lugar para fazer isso seria no viewWillAppear.