09 Mar, 2012 14:08

Teclados personalizados no iOS

Criando a KeyboardView

Para essa solução, utilizei uma view especial que poderia ser facilmente reaproveitada para diversos campos de texto. Primeiro, criei uma classe KeyboardView filha de UIView.

A função dessa classe é carregar a interface (XIB) do meu teclado, interceptar a mudança de foco nos campos, preencher os campos a partir do toque nas teclas e realizar o dismiss (fazer o campo perder o foco e, logo, o teclado desaparecer).

Eis o trecho mais relevante:

+ (id)keyboardView {
    NSArray *views = [[NSBundle mainBundle] loadNibNamed:@"KeyboardView" owner:nil options:nil];

    KeyboardView *keyboardView = [views objectAtIndex:0];

    [[NSNotificationCenter defaultCenter] addObserver:keyboardView selector:@selector(novoTextField:) name:UITextFieldTextDidBeginEditingNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:keyboardView selector:@selector(saidaTextField:) name:UITextFieldTextDidEndEditingNotification object:nil];

    return keyboardView;
}

- (void)novoTextField:(NSNotification *)notification {
    UITextField *novoTextField = [notification object];

    if (novoTextField.inputView == self) {
        self.textField = novoTextField;
    }
}

- (void)saidaTextField:(NSNotification *)notification {
    if ([notification object] == self.textField) {
        self.textField = nil;
    }
}

- (IBAction)teclou:(UIButton *)tecla {
    if (self.textField) {
        self.textField.text = [self.textField.text stringByAppendingString:tecla.titleLabel.text];
    }

}

- (IBAction)esconderTeclado:(id)sender {
    [self.textField resignFirstResponder];
}

Inicialmente, temos um método de classe para fazer a carga do XIB e preparar o nosso teclado para interceptar as mudanças de foco nos campos de texto.

Repare que para evitar criar uma rede de propriedades e/ou delegates, utilizei as notificações comuns do sistema para informar à minha KeyboardView qual é o campo que ela deve manipular.

Todas as teclas de edição estão vinculadas ao mesmo método (teclou:) e utilizei o texto do próprio UIButton selecionado para editar o campo de texto atual.

Para uma experiência completa, adicionei uma tecla "Voltar" para fechar o teclado e vinculei-a a ação (esconderTeclado:).

Utilizando a KeyboardView

Uma vez criada a classe acima, seu uso é trivial. Em um controller onde eu queria utilizar a KeyboardView com alguns campos, eu poderia fazer simplesmente:

- (void)viewDidLoad {
    [super viewDidLoad];

    KeyboardView *keyboardView = [KeyboardView keyboardView];

    numeroTextField.inputView = keyboardView;
    numero2TextField.inputView = keyboardView;
}

Repare que basta carregar uma instância da KeyboardView e atribuí-la à propriedade inputView dos campos que forem necessários. E voilá!

O resultado é semelhante ao abaixo.

Utilizando um teclado custom no iOS

O campo "Nome" possui um teclado normal. Os campos de "Número" estão utilizando a minha KeyboardView e são atualizados automaticamente quando selecionamos alguma tecla. Simples, não?

Considerações finais

A solução que apresentei, apesar de resolver a maioria dos problemas, não cobre alguns casos específico que você talvez precise tratar.

Suporte a UITextView

No exemplo, utilizei apenas UITextField mas também poderíamos utilizar UITextView. Para isso, bastaria observar também as notificações UITextViewTextDidBeginEditingNotification e UITextViewTextDidEndEditingNotification.

Relacionamento com os delegates

Quando utilizamos o teclado normal, os métodos de UITextFieldDelegate ou UITextViewDelegate são sempre acionados. Com o teclado personalizado, alguns métodos teriam de ser chamados explicitamente pela KeyboardView.

Layout do teclado

Nos testes que fiz, percebi que poderia colocar o teclado com qualquer altura, mas a largura era sempre forçada à largura máxima da tela. Contudo, se quiser um teclado com uma largura menor, é possível simular o efeito fazendo com que a view principal do teclado tenha fundo transparente e dimensionando qualquer subview da maneira que for mais adequada.

Ao navegar neste site, você consente o uso de cookies nossos e de terceiros, que coletam informações anônimas e são essenciais para melhorar sua experiência em nosso site.