Como posso navegar por todos os meus campos de texto com o botão "Avançar" no teclado do iPhone?
O último campo de texto deve fechar o teclado.
Eu configurei o IB the Buttons (Next / Done), mas agora estou preso.
Eu implementei a ação textFieldShouldReturn, mas agora os botões Avançar e Concluído fecham o teclado.
ios
objective-c
iphone
phx
fonte
fonte
Respostas:
No Cocoa para Mac OS X, você tem a próxima cadeia de respostas, onde é possível perguntar ao campo de texto qual controle deve ser o próximo foco. É isso que faz a tabulação entre os campos de texto funcionar. Mas como os dispositivos iOS não possuem teclado, apenas toque, esse conceito não sobreviveu à transição para o Cocoa Touch.
Isso pode ser feito facilmente de qualquer maneira, com duas suposições:
UITextField
estão na mesma visualização pai.Supondo que você possa substituir textFieldShouldReturn: como este:
Adicione um pouco mais de código e as suposições também podem ser ignoradas.
Swift 4.0
Se a super visão do campo de texto for um UITableViewCell, o próximo respondedor será
fonte
UITableViewCell
. Você precisaria acessar o associadoUITableView
e obter a célula que contém o campo de texto que você está procurando.UITextFieldDelegate
e definir os delegados dos campos de texto.Existe uma solução muito mais elegante que me surpreendeu na primeira vez que a vi. Benefícios:
UITextField
eUITextView
controles - ou qualquer controle da interface do usuário da entrada do tecladoCrie uma subclasse UITextField que tenha uma
IBOutlet
propriedade chamada nextField. Aqui está o cabeçalho:E aqui está a implementação:
No seu controlador de exibição, você criará o
-textFieldShouldReturn:
método delegate:No IB, altere seu UITextFields para usar a
SOTextField
classe Em seguida, também no IB, defina o delegado para cada um dos 'SOTextFields' para 'Proprietário do arquivo' (que é exatamente onde você coloca o código para o método de delegação - textFieldShouldReturn). A beleza desse design é que agora você pode simplesmente clicar com o botão direito do mouse em qualquer campo de texto e atribuir a saída nextField ao próximoSOTextField
objeto que você deseja que seja o próximo respondedor.Além disso, você pode fazer coisas legais como fazer um loop no campo de texto para que, depois que o último perca o foco, o primeiro receba o foco novamente.
Isso pode ser facilmente estendido para atribuir automaticamente a
returnKeyType
de aSOTextField
aUIReturnKeyNext
se houver um nextField atribuído - menos uma coisa configurada manualmente.fonte
UITableView
. Embora eu tenhaIBOutlet
propriedades no controlador de exibição para cada campo de texto, ele não menextField
permite vincular a propriedade a essas propriedades no Proprietário do arquivo. Algum conselho sobre como posso fazê-lo funcionar nesse cenário?textField1.nextField = textField2; textField2.nextField = textField3;
, etcAqui está um sem delegação:
ObjC:
Funciona usando a
UIControlEventEditingDidEndOnExit
UITextField
ação (principalmente desconhecida) .Você também pode conectar isso facilmente no storyboard, para que nenhuma delegação ou código seja necessário.
Edit: na verdade, eu não consigo descobrir como conectar isso no storyboard.
becomeFirstResponder
não parece ser uma ação oferecida para esse evento de controle, que é uma pena. Ainda assim, você pode conectar todos os seus campos de texto a uma única ação no seu ViewController, que determina qual o campo de texto combecomeFirstResponder
base no remetente (embora não seja tão elegante quanto a solução programática acima, para que o IMO faça isso com o código acimaviewDidLoad
).fonte
[tfN addTarget:self action:@selector(loginButtonTapped:) forControlEvents:UIControlEventEditingDidEndOnExit];
. Obrigado @mxcl.Aqui está a minha solução para este problema.
Para resolver isso (e porque eu odeio confiar em tags para fazer coisas), decidi adicionar uma propriedade personalizada ao objeto UITextField. Em outras palavras, eu criei uma categoria no UITextField assim:
UITextField + Extended.h
UITextField + Extended.m
Agora, aqui está como eu o uso:
E implemente o método textFieldShouldReturn:
Agora tenho um tipo de lista vinculada de UITextField, cada um sabendo quem é o próximo na fila.
Espero que ajude.
fonte
Uma extensão rápida que aplica a resposta do mxcl para tornar isso particularmente fácil (adaptado ao swift 2.3 pelo Traveler):
É fácil de usar:
A extensão definirá o botão de retorno como "Avançar" para todos, exceto o último campo, e "Concluído" para o último campo, e mudará o foco / dispensará o teclado quando estes forem tocados.
Swift <2.3
SWIFT 3: use assim -
fonte
UITextFieldDelegate
e implementadofunc textFieldDidEndEditing(textField: UITextField)
. Apenas volte mais cedo setextField != field3
.Uma maneira mais consistente e robusta é usar o NextResponderTextField Você pode configurá-lo totalmente a partir do construtor de interface, sem a necessidade de definir ou usar o delegado
view.tag
.Tudo que você precisa fazer é
UITextField
serNextResponderTextField
nextResponderField
para apontar para o próximo respondedor, pois pode ser qualquer coisaUITextField
ou qualquerUIResponder
subclasse. Também pode ser um UIButton e a biblioteca é inteligente o suficiente para acionar oTouchUpInside
evento do botão apenas se estiver ativado.Aqui está a biblioteca em ação:
fonte
Gosto das soluções OO que já foram sugeridas pelo Anth0 e pelo Answerbot. No entanto, eu estava trabalhando em um POC rápido e pequeno, então não queria desorganizar as coisas com subclasses e categorias.
Outra solução simples é criar um NSArray de campos e procurar o próximo campo quando você pressionar próximo. Não é uma solução OO, mas é rápida, simples e fácil de implementar. Além disso, você pode ver e modificar a ordem rapidamente.
Aqui está o meu código (criado com base em outras respostas neste tópico):
fonte
Aqui está uma implementação de tabulação usando uma categoria no UIControl. Esta solução tem todas as vantagens dos métodos de Michael e Anth0, mas funciona para todos os UIControls, não apenas para
UITextField
s. Também funciona perfeitamente com o Interface Builder e os storyboards.Aplicativo de origem e exemplo: repositório GitHub para UIControlsWithTabbing
Uso:
Cabeçalho:
Implementação:
fonte
Eu tentei muitos códigos e, finalmente, isso funcionou para mim no Swift 3.0 mais recente [março de 2017]
A
ViewController
classe deve ser herdadaUITextFieldDelegate
para fazer esse código funcionar.Adicione o campo Texto com o número de etiqueta apropriada e esse número de etiqueta é usado para levar o controle ao campo de texto apropriado com base no número de etiqueta incremental atribuído a ele.
No código acima, o
returnKeyType = UIReturnKeyType.next
where fará com que o teclado volte a ser exibido, poisNext
você também tem outras opções,Join/Go
etc., com base no seu aplicativo, altere os valores.Este
textFieldShouldReturn
é um método controlado por UITextFieldDelegate e aqui temos a próxima seleção de campo com base no incremento do valor do Tagfonte
UITextView
. Alguma idéia de como fazer isso em combinação?UITextField
(insira uma linha de texto) e a outra éUITextView
(insira várias linhas de texto).UITextView
obviamente não responde a esse código, mas pode ser usado em formulários.Depois de sair de um campo de texto, você chama [otherTextField becomeFirstResponder] e o próximo campo fica em foco.
Na verdade, esse pode ser um problema complicado, pois muitas vezes você também deseja rolar a tela ou ajustar a posição do campo de texto para facilitar a visualização ao editar. Apenas faça muitos testes para entrar e sair dos campos de texto de maneiras diferentes e também para sair mais cedo (sempre dê ao usuário a opção de descartar o teclado em vez de ir para o próximo campo, geralmente com "Concluído" em a barra de navegação)
fonte
fonte
Um método muito fácil de descartar o teclado quando o botão 'Concluído' é pressionado é:
Crie uma nova IBAction no cabeçalho
No arquivo de implementação (arquivo .m), adicione o seguinte método:
Então, quando você vincular o IBAction ao campo de texto - vincule ao evento 'Terminou na saída'.
fonte
Primeiro defina a tecla de retorno do teclado no xib, caso contrário, você poderá escrever o código em
viewdidload
:fonte
Estou surpreso com quantas respostas aqui não conseguem entender um conceito simples: navegar pelos controles no seu aplicativo não é algo que as próprias visualizações devem fazer. É o controlador é decidir qual controle deve ser o próximo responsável pela resposta.
Além disso, a maioria das respostas se aplica apenas à navegação para frente, mas os usuários também podem querer retroceder.
Então aqui está o que eu criei. Seu formulário deve ser gerenciado por um controlador de exibição, e os controladores de exibição fazem parte da cadeia de respostas. Portanto, você está perfeitamente livre para implementar os seguintes métodos:
Pode ser aplicada lógica adicional para rolar os respondedores fora da tela visíveis antes.
Outra vantagem dessa abordagem é que você não precisa subclassificar todos os tipos de controles que deseja exibir,
UITextField
mas pode gerenciar a lógica no nível do controlador, onde, sejamos honestos, é o lugar certo para fazer isso .fonte
Eu adicionei à resposta do PeyloW caso você esteja procurando implementar uma funcionalidade de botão anterior / seguinte:
Onde você subclassifica o UIView assim:
fonte
Olá a todos, por favor, veja este
fonte
Tentei resolver esse problema usando uma abordagem mais sofisticada baseada na atribuição de cada célula (ou
UITextField
) em umUITableView
valor de tag exclusivo que pode ser recuperado posteriormente: enable-next-uitextfield-in-uitableview-iosEu espero que isso ajude!
fonte
Acabei de criar um novo Pod ao lidar com esse material GNTextFieldsCollectionManager . Ele lida automaticamente com o próximo / último problema do textField e é muito fácil de usar:
Agarra todos os campos de texto classificados por aparecer na hierarquia de exibição (ou por tags), ou você pode especificar sua própria matriz de campos de texto.
fonte
Solução no Swift 3.1, depois de conectar seus campos de texto, IBOutlets defina seu delegado de campos de texto em viewDidLoad e navegue sua ação em textFieldShouldReturn
fonte
Se alguém quiser assim. Eu acho que este é o mais próximo dos requisitos solicitados em questão
Aqui está como eu implementei este
Adicione visualização acessória para cada campo de texto para o qual você deseja configurar, usando
Use as seguintes funções para lidar com torneiras
Você precisará fornecer as tags textFields na sequência em que deseja que o botão próximo / anterior responda.
fonte
Prefiro:
No arquivo NIB, conecto os textFields na ordem desejada a esse array inputFields. Depois disso, faço um teste simples para o índice do UITextField que informa que o usuário tocou em retornar:
fonte
fonte
Eu tinha cerca de 10+ UITextField no meu storyboard e a maneira como habilitei a próxima funcionalidade foi criar uma matriz de UITextField e tornar o próximo UITextField o firstResponder. Aqui está o arquivo de implementação:
fonte
Isso funcionou para mim no Xamarin.iOS / Monotouch. Altere o botão do teclado para Avançar, passe o controle para o próximo UITextField e oculte o teclado após o último UITextField.
Dentro do ViewDidLoad, você terá:
Se seus TextFields não tiverem um Tag, defina-o agora:
e apenas a ligação
fonte
Esta é uma solução simples, rápida, sem uso de tags, sem truques de storyboard ...
Basta usar esta extensão:
E chame assim (por exemplo) com seu delegado do campo de texto:
fonte
Uma maneira mais segura e direta, assumindo:
Swift 4.1:
fonte
em textFieldShouldReturn, verifique se o campo de texto em que você está atualmente não é o último quando clica em Avançar e se ele não dispensa o teclado.
fonte
Este é um post antigo, mas tem um alto page rank, por isso vou falar com minha solução.
Eu tive um problema semelhante e acabei criando uma subclasse de
UIToolbar
para gerenciar a funcionalidade próxima / anterior / concluída em uma tabela dinâmica.Ver com seções: https://github.com/jday001/DataEntryToolbarVocê define a barra de ferramentas como inputAccessoryView dos seus campos de texto e os adiciona ao seu dicionário. Isso permite que você alterne entre eles para frente e para trás, mesmo com conteúdo dinâmico. Existem métodos delegados se você deseja acionar sua própria funcionalidade quando a navegação textField acontece, mas você não precisa lidar com o gerenciamento de nenhuma tag ou status de respondedor.
Existem trechos de código e um aplicativo de exemplo no link do GitHub para ajudar nos detalhes da implementação. Você precisará de seu próprio modelo de dados para acompanhar os valores dentro dos campos.
fonte
Sem usar tags e sem adicionar uma propriedade para nextField / nextTextField, você pode tentar emular TAB, onde "testInput" é o seu campo ativo atual:
fonte
Estou usando a resposta de Michael G. Emmons há cerca de um ano, funciona muito bem. Recentemente, notei que chamar resignFirstResponder e, em seguida, tornar-seFirstResponder imediatamente pode causar uma falha no teclado, desaparecendo e aparecendo imediatamente. Alterei a versão dele ligeiramente para pular o resignFirstResponder se o nextField estiver disponível.
fonte