¿Cómo puedo detectar cualquier cambio de texto en un campo de texto? El método delegado shouldChangeCharactersInRange
funciona para algo, pero no satisfizo exactamente mi necesidad. Como hasta que devuelve SÍ, los textos textField no están disponibles para otros métodos de observación.
Por ejemplo, en mi código calculateAndUpdateTextFields
no recibí el texto actualizado, el usuario ha escrito.
Es su forma de obtener algo como el textChanged
controlador 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;
}
Respuestas:
De la manera correcta de hacer un cambio de texto uitextfield, devuelva la llamada :
En el objetivo-C:
En Swift:
Podría usar eso y poner CalculateAndUpdateTextFields como su
selector
.fuente
NO
, lo cual es lógico, porque cuando regresasNO
de este método, básicamente estás diciendo que el texto en el campo no debería cambiar.textField.text = "Some new value";
. ¿Hay alguna manera inteligente de atrapar esto?UITextFieldDelegate
que algo asífunc textField: UITextField, didChangeText text: String
se habría incluido, pero ... (le da a los chicos de Apple una mirada sucia)La respuesta de XenElement es acertada.
Lo anterior también se puede hacer en el generador de interfaces haciendo clic derecho en UITextField y arrastrando el evento de envío "Edición modificada" a su unidad de subclase.
fuente
para configurar el oyente del evento:
para escuchar realmente:
fuente
Rápido:
Luego, implemente la función de devolución de llamada:
fuente
Como se indica aquí: evento de cambio de texto UITextField , parece que a partir de iOS 6 (iOS 6.0 y 6.1 verificado) no es posible detectar completamente los cambios en los
UITextField
objetos simplemente observando elUITextFieldTextDidChangeNotification
.Parece que ahora solo se rastrean los cambios realizados directamente por el teclado iOS incorporado. Esto significa que si cambia su
UITextField
objeto simplemente invocando algo como esto:myUITextField.text = @"any_text"
no se le notificará ningún cambio.No sé si esto es un error o si está destinado. Parece un error ya que no he encontrado ninguna explicación razonable en la documentación. Esto también se indica aquí: evento de cambio de texto UITextField .
Mi "solución" para esto es publicar una notificación por mí mismo por cada cambio que realice en mi
UITextField
(si ese cambio se realiza sin usar el teclado iOS incorporado). Algo como esto:De esta manera, está 100% seguro de que recibirá la misma notificación cuando cambie la
.text
propiedad de suUITextField
objeto, ya sea cuando lo actualice "manualmente" en su código o mediante el teclado iOS incorporado.Es importante tener en cuenta que, dado que este no es un comportamiento documentado, este enfoque puede dar lugar a 2 notificaciones recibidas para el mismo cambio en su
UITextField
objeto. Dependiendo de sus necesidades (lo que realmente hace cuandoUITextField.text
cambia), esto podría ser un inconveniente para usted.Un enfoque ligeramente diferente sería publicar una notificación personalizada (es decir, con un nombre personalizado diferente a
UITextFieldTextDidChangeNotification
) si realmente necesita saber si la notificación fue suya o "hecha por iOS".EDITAR:
Acabo de encontrar un enfoque diferente que creo que podría ser mejor:
Esto implica la característica de Observación de valores clave (KVO) de Objective-C ( http://developer.apple.com/library/ios/#documentation/cocoa/conceptual/KeyValueObserving/KeyValueObserving.html#//apple_ref/doc/uid / 10000177-BCICJDHA ).
Básicamente, usted se registra como observador de una propiedad y si esta propiedad cambia, se le notificará al respecto. El "principio" es bastante similar a cómo
NSNotificationCenter
funciona, siendo la principal ventaja de que este enfoque funciona automáticamente también a partir de iOS 6 (sin ningún ajuste especial como tener que publicar notificaciones manualmente).Para nuestro
UITextField
-scenario, esto funciona bien si agrega este código a, por ejemplo, elUIViewController
que contiene el campo de texto:Crédito a esta respuesta con respecto a la gestión del "contexto": https://stackoverflow.com/a/12097161/2078512
Nota: Parece que mientras está en el proceso de editar un
UITextField
con el teclado iOS incorporado, la propiedad "texto" del campo de texto no se actualiza con cada nueva letra escrita / eliminada. En cambio, el objeto de campo de texto se actualiza "en su conjunto" después de que renuncia al primer estado de respuesta del campo de texto.fuente
Podemos configurarlo fácilmente
Storyboard
, arrastrar CTRL@IBAction
y cambiar el evento de la siguiente manera:fuente
Aquí en versión rápida para lo mismo.
Gracias
fuente
Resolví el problema cambiando el comportamiento de shouldChangeChractersInRange. Si devuelve NO, iOS no aplicará los cambios internamente, sino que tiene la oportunidad de cambiarlos manualmente y realizar cualquier acción después de los cambios.
fuente
Versión Swift probada:
Parámetros explicados:
Luego agregue el método que creó anteriormente en su
UIViewController
:fuente
Swift 4
fuente
Para Swift 3.0:
usando clase como:
fuente
Versión Swift 3
Y obtén los cambios aquí
Espero eso ayude.
fuente
Debe usar la notificación para resolver este problema, porque el otro método escuchará el cuadro de entrada, no la entrada real, especialmente cuando usa el método de entrada chino. En vista Descarga
entonces
}
finalmente, corres, listo.
fuente
Swift 3.1:
fuente
Versión Swift 3:
No olvide configurar el delegado.
fuente
Con cierre:
y usando
fuente
KVO NO funciona en iOS para controles: http://stackoverflow.com/a/6352525/1402846 https://developer.apple.com/library/archive/documentation/General/Conceptual/DevPedia-CocoaCore/KVO.html
Dado que conoce la vista de texto que desea ver:
Hacer esto:
Sin embargo, tenga cuidado con eso:
es probable que solo quieras llamar así una vez , así que no lo llames, por ejemplo,
layoutSubviews
es bastante difícil saber cuándo llamarlo mejor durante el proceso de actualización Dependerá de tu situación. Lamentablemente, no existe una solución estándar bloqueada
por ejemplo, por lo general, no puede llamarlo a
init
tiempo, ya que, por supuestowatchedTextView
, aún no existe.
Ninguna de las notificaciones se llama cuando el texto se cambia mediante programación .
Esta es una molestia enorme, antigua y estúpida en la ingeniería de iOS.
Los controles simplemente no, al final de la historia , llaman a las notificaciones cuando la propiedad .text se cambia mediante programación.
Esto es increíblemente molesto porque, por supuesto, obviamente, cada aplicación creada establece el texto mediante programación, como borrar el campo después de que el usuario publica, etc.
Debe subclasificar la vista de texto (o control similar) de esta manera:
(Consejo: ¡no olvide que la súper llamada tiene que venir antes ! La llamada posterior).
No hay una solución disponible, a menos que arregle el control subclasificando como se muestra arriba. Ese es el unico solución.
Tenga en cuenta que la notificación
resultados en
siendo llamado.
( No
textViewDidChange
)fuente
fuente
Una cosa es que puede tener múltiples UITextFields. Entonces, deles una etiqueta y luego puede encender las etiquetas. Aquí se explica cómo configurar un observador en cualquier clase.
fuente
Versión Swift 4
Uso de la observación de valores clave Notifique a los objetos sobre los cambios en las propiedades de otros objetos.
fuente