Como posso detectar alterações de texto em um campo de texto? O método delegado shouldChangeCharactersInRange
funciona para algo, mas não atendeu exatamente minha necessidade. Como até retornar YES, os textos textField não estarão disponíveis para outros métodos de observação.
por exemplo, no meu código calculateAndUpdateTextFields
não recebeu o texto atualizado, o usuário digitou.
É sua maneira de obter algo como o textChanged
manipulador de eventos Java.
- (BOOL)textField:(UITextField *)textField
shouldChangeCharactersInRange:(NSRange)range
replacementString:(NSString *)string
{
if (textField.tag == kTextFieldTagSubtotal
|| textField.tag == kTextFieldTagSubtotalDecimal
|| textField.tag == kTextFieldTagShipping
|| textField.tag == kTextFieldTagShippingDecimal)
{
[self calculateAndUpdateTextFields];
}
return YES;
}
Respostas:
Da maneira correta de fazer a alteração de texto do uitextfield, ligue de volta :
No Objetivo-C:
Em Swift:
Você pode usar isso e colocar o calculAndUpdateTextFields como seu
selector
.fonte
NO
, o que é lógico, porque quando você retornaNO
desse método, está basicamente dizendo que o texto no campo não deve mudar.textField.text = "Some new value";
. Existe uma maneira inteligente de entender isso?UITextFieldDelegate
que algo comofunc textField: UITextField, didChangeText text: String
teria sido incluído, mas ... (dá caras na Apple um olhar sujo)A resposta do XenElement é imediata.
O procedimento acima também pode ser feito no criador de interface, clicando com o botão direito do mouse no UITextField e arrastando o evento de envio "Editing Changed" para sua unidade de subclasse.
fonte
para definir o ouvinte de evento:
para realmente ouvir:
fonte
Rápido:
Em seguida, implemente a função de retorno de chamada:
fonte
Conforme declarado aqui: evento de alteração de texto UITextField , parece que a partir do iOS 6 (iOS 6.0 e 6.1 marcado) não é possível detectar completamente as alterações nos
UITextField
objetos apenas observando oUITextFieldTextDidChangeNotification
.Parece que apenas as alterações feitas diretamente pelo teclado interno do iOS são rastreadas agora. Isso significa que se você alterar seu
UITextField
objeto apenas invocando algo como isto:,myUITextField.text = @"any_text"
você não será notificado sobre nenhuma alteração.Não sei se isso é um bug ou se destina. Parece um bug, pois não encontrei nenhuma explicação razoável na documentação. Isso também é afirmado aqui: Evento de alteração de texto UITextField .
Minha "solução" para isso é realmente postar uma notificação por mim mesmo para cada alteração que fizer no meu
UITextField
(se essa alteração for feita sem o uso do teclado iOS incorporado). Algo assim:Dessa forma, você está 100% confiante de que receberá a mesma notificação quando alterar a
.text
propriedade do seuUITextField
objeto, quando o atualizar "manualmente" em seu código ou por meio do teclado iOS incorporado.É importante considerar que, como esse não é um comportamento documentado, essa abordagem pode levar a duas notificações recebidas pela mesma alteração em seu
UITextField
objeto. Dependendo das suas necessidades (o que você realmente faz quando asUITextField.text
alterações são feitas), isso pode ser um inconveniente para você.Uma abordagem ligeiramente diferente seria postar uma notificação personalizada (ou seja, com um nome personalizado diferente de
UITextFieldTextDidChangeNotification
) se você realmente precisar saber se a notificação foi sua ou "feita pelo iOS".EDITAR:
Acabei de encontrar uma abordagem diferente que eu acho que poderia ser melhor:
Isso envolve o recurso Observação de Valor-Chave (KVO) do Objective-C ( http://developer.apple.com/library/ios/#documentation/cocoa/conceptual/KeyValueObserving/KeyValueObserving.html#//apple_ref/doc/uid / 10000177-BCICJDHA ).
Basicamente, você se registra como um observador de uma propriedade e, se essa propriedade mudar, você será notificado. O "princípio" é bastante semelhante ao modo como
NSNotificationCenter
funciona, sendo a principal vantagem que essa abordagem funciona automaticamente também no iOS 6 (sem nenhum ajuste especial, como ter que postar notificações manualmente).Para o nosso
UITextField
cenário, isso funciona muito bem se você adicionar esse código, por exemplo, o seuUIViewController
que contém o campo de texto:Os créditos a esta resposta sobre o gerenciamento de "contexto": https://stackoverflow.com/a/12097161/2078512
Nota: Parece que enquanto você está no processo de edição de um
UITextField
com o built-in teclado iOS, a propriedade "texto" do campo de texto não é atualizado a cada nova letra digitada / removido. Em vez disso, o objeto do campo de texto é atualizado "como um todo" após você renunciar ao status de primeiro respondedor do campo de texto.fonte
Podemos facilmente configurar isso a partir de
Storyboard
CTRL, arraste o@IBAction
evento e altere da seguinte maneira:fonte
Aqui na versão rápida para o mesmo.
obrigado
fonte
Resolvi o problema alterando o comportamento de shouldChangeChractersInRange. Se você retornar NÃO, as alterações não serão aplicadas internamente pelo iOS; em vez disso, você terá a oportunidade de alterá-lo manualmente e executar quaisquer ações após as alterações.
fonte
Versão Swift testada:
Parâmetros explicados:
Em seguida, adicione o método que você criou acima em seu
UIViewController
:fonte
Swift 4
fonte
Para o Swift 3.0:
usando classe como:
fonte
Versão Swift 3
E obtenha as mudanças aqui
Espero que ajude.
fonte
Você deve usar a notificação para resolver esse problema, porque o outro método escutará a caixa de entrada e não a entrada realmente, especialmente quando você usar o método de entrada chinês. In viewDidload
então
}
finalmente, você corre, será feito.
fonte
Swift 3.1:
fonte
Versão Swift 3:
Não se esqueça de definir o delegado.
fonte
Com fechamento:
e usando
fonte
O KVO NÃO funciona no iOS para controles: http://stackoverflow.com/a/6352525/1402846 https://developer.apple.com/library/archive/documentation/General/Conceptual/DevPedia-CocoaCore/KVO.html
Como você conhece a exibição de texto que deseja assistir:
Faça isso:
No entanto, tenha cuidado com isso:
é provável que você queira chamá-lo apenas uma vez . Portanto, não ligue, por exemplo,
layoutSubviews
é muito difícil saber quando melhor chamá-lo durante o processo de abertura. Vai depender da sua situação. Infelizmente, não existe uma solução padrão bloqueada
por exemplo, você normalmente pode certamente não chamá-lo no
init
tempo, desde que, naturalmente,watchedTextView
pode não existir ainda.
Nenhuma das notificações é chamada quando o texto é alterado programaticamente .
Esse é um incômodo enorme, antigo e estúpido na engenharia do iOS.
Os controles simplesmente não chamam as notificações quando a propriedade .text é alterada programaticamente.
Isso é incrivelmente irritante, porque é claro - obviamente - todos os aplicativos já criados definem o texto programaticamente, como limpar o campo depois que o usuário postar etc.
Você deve subclassificar a exibição de texto (ou controle semelhante) desta forma:
(Dica - não se esqueça que a super chamada deve ocorrer antes ! A pós-chamada.)
Não há solução disponível, a menos que você corrija o controle subclassificando conforme mostrado acima. Essa é a única solução.
Observe que a notificação
resulta em
sendo chamado.
( Não
textViewDidChange
.)fonte
fonte
Uma coisa é que você pode ter vários UITextFields. Então, dê a eles uma tag e você poderá ativá-las. Veja como configurar um observador em qualquer classe praticamente.
fonte
Versão Swift 4
Usando a observação do valor-chave Notificar objetos sobre alterações nas propriedades de outros objetos.
fonte