valuechanged uitextfieldtextdidchangenotification textfielddidchange change ios objective-c swift event-handling uitextfielddelegate

ios - uitextfieldtextdidchangenotification - UITextField evento de cambio de texto



uitextfield valuechanged swift (18)

Aquí en versión veloz por igual.

textField.addTarget(self, action: "textFieldDidChange:", forControlEvents: UIControlEvents.EditingChanged) func textFieldDidChange(textField: UITextField) { }

Gracias

¿Cómo puedo detectar cualquier cambio de texto en un campo de texto? El método delegado shouldChangeCharactersInRange funciona para algo, pero no satisface exactamente mi necesidad. Desde que hasta que devuelva SÍ, los textos textField no están disponibles para otros métodos de observación.

Por ejemplo, en mi código, calculateAndUpdateTextFields no obtuvo el texto actualizado, el usuario ha escrito.

Es su forma de obtener algo como el controlador de eventos textChanged 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; }


Como se indica aquí: evento de cambio de texto de UITextField , parece que a partir de iOS 6 (iOS 6.0 y 6.1 marcados) no es posible detectar completamente los cambios en los objetos de UITextField simplemente observando el UITextFieldTextDidChangeNotification .

Parece que ahora solo se realiza un seguimiento de los cambios realizados directamente por el teclado iOS incorporado. Esto significa que si cambia su objeto UITextField simplemente invocando algo como esto: myUITextField.text = @"any_text" , no se le notificará ningún cambio en absoluto.

No sé si esto es un error o 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 de UITextField .

Mi "solución" a 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 integrado). Algo como esto:

myUITextField.text = @"I''m_updating_my_UITextField_directly_in_code"; NSNotification *myTextFieldUpdateNotification = [NSNotification notificationWithName:UITextFieldTextDidChangeNotification object:myUITextField]; [NSNotificationCenter.defaultCenter postNotification:myTextFieldUpdateNotification];

De esta manera, está 100% seguro de que recibirá la misma notificación cuando cambie la propiedad .text de su objeto UITextField , 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 llevar a 2 notificaciones recibidas por el mismo cambio en su objeto UITextField . Dependiendo de sus necesidades (lo que realmente hace cuando cambia su UITextField.text ) 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 que no sea 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 valor-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 notifica al respecto. El "principio" es bastante similar a cómo funciona NSNotificationCenter , siendo la principal ventaja que este enfoque funciona automáticamente también en iOS 6 (sin ninguna modificación especial como tener que publicar notificaciones manualmente).

Para nuestro UITextField -scenario, esto funciona bien si agrega este código a, por ejemplo, su UIViewController que contiene el campo de texto:

static void *myContext = &myContext; - (void)viewDidLoad { [super viewDidLoad]; //Observing changes to myUITextField.text: [myUITextField addObserver:self forKeyPath:@"text" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:myContext]; } - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { if(context == myContext) { //Here you get notified every time myUITextField''s "text" property is updated NSLog(@"New value: %@ - Old value: %@", [change objectForKey:NSKeyValueChangeNewKey], [change objectForKey:NSKeyValueChangeOldKey]); } else [super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; }

Gracias a esta respuesta con respecto a la administración de "contexto": https://.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 su lugar, el objeto de campo de texto se actualiza "en conjunto" después de que renuncies al primer estado de respuesta del campo de texto.


Con cierre:

class TextFieldWithClosure: UITextField { var targetAction: (() -> Void)? { didSet { self.addTarget(self, action: #selector(self.targetSelector), for: .editingChanged) } } func targetSelector() { self.targetAction?() } }

y usando

textField.targetAction? = { // will fire on text changed }


Debe usar la notificación para resolver este problema, porque el otro método escuchará el cuadro de entrada y no la entrada real, especialmente cuando use el método de entrada chino. En la vistaDescargar

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textFiledEditChanged:) name:@"UITextFieldTextDidChangeNotification" object:youTarget];

entonces

- (void)textFiledEditChanged:(NSNotification *)obj { UITextField *textField = (UITextField *)obj.object; NSString *toBestring = textField.text; NSArray *currentar = [UITextInputMode activeInputModes]; UITextInputMode *currentMode = [currentar firstObject]; if ([currentMode.primaryLanguage isEqualToString:@"zh-Hans"]) { UITextRange *selectedRange = [textField markedTextRange]; UITextPosition *position = [textField positionFromPosition:selectedRange.start offset:0]; if (!position) { if (toBestring.length > kMaxLength) textField.text = toBestring; }

}

Finalmente, corres, lo harás.


Desde la forma correcta de hacer el cambio de texto de uitextfield devuelva la llamada :

Capto los caracteres enviados a un control de UITextField algo como esto:

// Add a "textFieldDidChange" notification method to the text field control. [textField addTarget:self action:@selector(textFieldDidChange:) forControlEvents:UIControlEventEditingChanged];

Luego, en el método textFieldDidChange: puede examinar el contenido de textField y volver a cargar la vista de tabla según sea necesario.

Usted podría usar eso y poner a CalculateAndUpdateTextFields como su selector .


Es realmente simple con observador y swift reactivo (RxCocoa y RxSwift).

Solo suscríbete a la propiedad de texto de rx, como abajo:

myTextField.rx.text.subscribe { text in print("UITextFieldTextChangeEvent Text:/(text)") }.disposed(by: disposeBag)


La respuesta de XenElement es acertada.

Lo anterior también se puede hacer en el constructor de interfaces haciendo clic con el botón derecho en el UITextField y arrastrando el evento de envío "Editing Changed" a su unidad de subclase.


Para Swift 3.0:

let textField = UITextField() textField.addTarget( nil, action: #selector(MyClass.textChanged(_:)), for: UIControlEvents.editingChanged )

usando clase como:

class MyClass { func textChanged(sender: Any!) { } }


Podemos configurarlo fácilmente desde Storyboard , CTRL arrastre la @IBAction y cambie el evento de la siguiente manera:


Resolví el problema cambiando el comportamiento de shouldChangeChractersInRange. Si devuelve NO, los cambios no serán aplicados internamente por iOS, en su lugar, tiene la oportunidad de cambiarlos manualmente y realizar cualquier acción después de los cambios.

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string { //Replace the string manually in the textbox textField.text = [textField.text stringByReplacingCharactersInRange:range withString:string]; //perform any logic here now that you are sure the textbox text has changed [self didChangeTextInTextField:textField]; return NO; //this make iOS not to perform any action }


Swift 3.1:

Selector: ClassName.MethodName

cell.lblItem.addTarget(self, action: #selector(NewListScreen.fieldChanged(textfieldChange:)), for: .editingChanged) func fieldChanged(textfieldChange: UITextField){ }


Versión Swift 3:

class SomeClass: UIViewController, UITextFieldDelegate { @IBOutlet weak var aTextField: UITextField! override func viewDidLoad() { super.viewDidLoad() aTextField.delegate = self aTextField.addTarget(self, action: #selector(SignUpVC.textFieldDidChange), for: UIControlEvents.editingChanged) } func textFieldDidChange(_ textField: UITextField) { //TEXT FIELD CHANGED..SECRET STUFF } }

No te olvides de configurar el delegado.


para configurar el oyente del evento:

[self.textField addTarget:self action:@selector(textFieldDidChange:) forControlEvents:UIControlEventEditingChanged];

para escuchar realmente

- (void)textFieldDidChange:(UITextField *)textField { NSLog(@"text changed: %@", textField.text); }


Rápido:

yourTextfield.addTarget(self, action: #selector(textFieldDidChange(textField:)), for: .editingChanged)

Luego, implemente la función de devolución de llamada:

@objc func textFieldDidChange(textField: UITextField){ print("Text changed") }


Swift 4

func addNotificationObservers() { NotificationCenter.default.addObserver(self, selector: #selector(textFieldDidChangeAction(_:)), name: .UITextFieldTextDidChange, object: nil) } @objc func textFieldDidChangeAction(_ notification: NSNotification) { let textField = notification.object as! UITextField print(textField.text!) }


Versión Swift 3

yourTextField.addTarget(self, action: #selector(YourControllerName.textChanges(_:)), for: UIControlEvents.editingChanged)

Y recibe los cambios aquí.

func textChanges(_ textField: UITextField) { let text = textField.text! // your desired text here // Now do whatever you want. }

Espero eso ayude.


Versión Swift probada:

//Somewhere in your UIViewController, like viewDidLoad(){ ... } self.textField.addTarget( self, action: #selector(SearchViewController.textFieldDidChange(_:)), forControlEvents: UIControlEvents.EditingChanged )

Parámetros explicados:

self.textField //-> A UITextField defined somewhere in your UIViewController self //-> UIViewController .textFieldDidChange(_:) //-> Can be named anyway you like, as long as it is defined in your UIViewController

Luego agregue el método que creó anteriormente en su UIViewController :

//Gets called everytime the text changes in the textfield. func textFieldDidChange(textField: UITextField){ print("Text changed: " + textField.text!) }


[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didChangeTextViewText:) name:UITextFieldTextDidChangeNotification object:nil]; - (void) didChangeTextViewText { //do something }