Respondendo a eventos de teclado no iOS

Um testador beta recentemente perguntou se eu poderia implementar alguns atalhos de teclado além do padrão selecionar, copiar, colar, etc. Não achei que fosse viável na época, mas com alguma ajuda de @antijingoist ( https://alpha.app .net / antijingoist ) e esta postagem no Stack Overflow me lembrando da inputViewpropriedade ( http://stackoverflow.com/questions/3397339/keyboard-shortcuts-in-ios ), descobri que poderia responder a pressionamentos de tecla regulares. Por regular, quero dizer letras, números, etc. As teclas de seta, infelizmente, não funcionam.

Veja como eu fiz, e você pode experimentar, melhorar, criticar sem parar – o que você quiser. Tenho certeza de que essa não é a melhor ou a maneira certa de fazer isso, mas parece estar funcionando até agora para mim. [ Tenho certeza de que é aprovado pela Apple? Não. Portanto, se seu aplicativo for rejeitado por causa disso, você foi avisado. ]

Primeiro, fiz minha viewControlleradesão ao UIKeyInputprotocolo:

@interface myViewController: UIViewController <UIKeyInput>
...

Em segundo lugar, perto do final do código do meu controlador, adicionei estes métodos:

-(void) deleteBackward: (id)sender
{
return;
}

-(BOOL) hasText
{
return YES;
}

-(void) insertText:(NSString *)text
{
static NSDate *lastKeypress;
NSTimeInterval lastKeypressInterval = [lastKeypress timeIntervalSince1970];
NSDate *thisKeypress = [NSDate date];
NSTimeInterval thisKeypressInterval = [thisKeypress timeIntervalSince1970];
if (thisKeypressInterval > lastKeypressInterval + 0.5)
{
lastKeypress
= thisKeypress;
if ([text isEqualToString:@"W"])
{
// go to top of page
}
if ([text isEqualToString:@"w"])
{
// go up a row
}
...
}
...
}

A ideia aqui é, uma vez que não consigo capturar as teclas de seta, farei com WASD. Para mim, faz sentido ter um shift + W indo para o topo, enquanto um W normal não deslocado apenas subir um pouco, daí a diferença acima, mas você poderia fazer a mesma coisa independentemente do caso.

Agora, tenho alguma verificação de debounce acontecendo aqui, já que às vezes as chaves pareciam disparar o código mais de uma vez. Restringir a resposta a cada 500 ms pareceu ajudar, mas se você precisar de uma resposta melhor, terá que recusar ou eliminá-la totalmente.

Em seguida, você viewControllerprecisa indicar também que pode ser o primeiro a responder:

-(BOOL) canBecomeFirstResponder
{
return YES;
}

E sua visão precisa se tornar uma primeira resposta em algum ponto (digamos viewDidAppear):

[self becomeFirstResponder];

Tudo funciona muito bem – mas, por um lado: aquele teclado virtual irritante que atrapalha. Poderíamos ajustar nossa IU para permitir isso, mas por quê? Estamos implementando atalhos de teclado e, sem um teclado de hardware conectado, o toque é muito mais preferível.

Acontece que podemos substituir inputView. Primeiro, em seu arquivo:.h

@property (strong, nonatomic, readwrite) UIView * inputView;

E então em seu controlador viewDidLoad:

self.inputView = [[UIView alloc] initWithFrame: CGRectMake(0,0,0,0)];

Adivinha – o teclado virtual vai embora (uma vez que tenta exibir uma visualização sem largura ou altura), mas ainda obtemos os eventos .

Portanto, embora não tenhamos as teclas de seta, vou levar isso por enquanto. Ele deve atender às necessidades de meus usuários avançados, sem atrapalhar os usuários que não se importam com essas coisas.

Se você tem uma maneira melhor ou sabe se a Apple rejeitará aplicativos que façam isso, ficarei feliz em saber.

Ah, e você pode me seguir @photokandy no Twitter ou App.net se quiser bater um papo.