Question Événement de modification de texte UITextField


Comment puis-je détecter les modifications de texte dans un textField? La méthode de délégué shouldChangeCharactersInRange travaille pour quelque chose, mais cela ne répondait pas exactement à mes besoins. Tant que YES n'est pas renvoyé, les textes textField ne sont pas disponibles pour les autres méthodes d'observation.

par exemple. dans mon code calculateAndUpdateTextFields n'a pas obtenu le texte mis à jour, l'utilisateur a tapé.

Est-ce que leur façon d'obtenir quelque chose comme textChanged Gestionnaire d'événements 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;
}

462
2017-08-10 12:09


origine


Réponses:


De bonne façon de faire un changement de texte uitextfield rappeler:

J'attrape les caractères envoyés à un contrôle UITextField comme suit:

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

Ensuite, dans la méthode textFieldDidChange: vous pouvez examiner le contenu de textField et recharger votre vue de table si nécessaire.

Vous pourriez l'utiliser et mettre CalculateAndUpdateTextFields comme votre selector.


923
2017-08-10 12:21



La réponse de XenElement est sur place.

Le peut être fait ci-dessus dans le constructeur d'interface trop en cliquant droit sur le UITextField et en faisant glisser l'événement envoyer « Edition Changed » à votre unité de sous-classe.

UITextField Change Event


342
2017-12-05 17:36



définir l'écouteur d'événement:

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

écouter réellement:

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

112
2018-06-06 08:25



Rapide:

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

Ensuite, implémentez la fonction de rappel:

@objc func textFieldDidChange(textField: UITextField){

print("Text changed")

}

52
2018-03-14 22:00



Comme indiqué ici: Événement de modification de texte UITextField, Il paraît que à partir d'iOS 6 (iOS 6.0 et 6.1 vérifiés) il n'est pas possible de détecter complètement les changements dans UITextField objets juste en observant le UITextFieldTextDidChangeNotification.

Il semble que seules les modifications apportées directement par le clavier iOS intégré sont suivies maintenant. Cela signifie que si vous changez votre UITextField objet en invoquant quelque chose comme ceci: myUITextField.text = @"any_text", vous ne serez pas averti de tout changement.

Je ne sais pas si c'est un bug ou s'il est destiné. Cela semble être un bug car je n'ai trouvé aucune explication raisonnable dans la documentation. Ceci est également indiqué ici: Événement de modification de texte UITextField.

Ma "solution" à ceci est d'afficher une notification par moi-même pour chaque changement que je fais à mon UITextField (si ce changement est effectué sans utiliser le clavier iOS intégré). Quelque chose comme ça:

myUITextField.text = @"I'm_updating_my_UITextField_directly_in_code";

NSNotification *myTextFieldUpdateNotification  = 
  [NSNotification notificationWithName:UITextFieldTextDidChangeNotification
                  object:myUITextField];

[NSNotificationCenter.defaultCenter 
  postNotification:myTextFieldUpdateNotification];

De cette façon, vous êtes sûr à 100% que vous recevrez la même notification lorsque vous modifiez le .text propriété de votre UITextField objet, soit lorsque vous le mettez à jour "manuellement" dans votre code ou via le clavier iOS intégré.

Il est important de considérer que, puisqu'il ne s'agit pas d'un comportement documenté, cette approche peut conduire à 2 notifications reçues pour le même changement dans votre UITextField objet. Selon vos besoins (ce que vous faites réellement lorsque votre UITextField.text changements) cela pourrait être un inconvénient pour vous.

Une approche légèrement différente consisterait à publier une notification personnalisée (c'est-à-dire avec un nom personnalisé autre que UITextFieldTextDidChangeNotification) si vous avez réellement besoin de savoir si la notification était la vôtre ou "faite par iOS".

MODIFIER:

Je viens de trouver une approche différente qui, selon moi, pourrait être meilleure:

Cela implique le Key-Value Observing (KVO) caractéristique d'Objective-C (http://developer.apple.com/library/ios/#documentation/cocoa/conceptual/KeyValueObserving/KeyValueObserving.html#//apple_ref/doc/uid/10000177-BCICJDHA).

Fondamentalement, vous vous inscrivez en tant qu'observateur d'une propriété et si cette propriété change, vous en êtes averti. Le "principe" est assez similaire à comment NSNotificationCenter fonctionne, étant le principal avantage que cette approche fonctionne automatiquement aussi à partir de iOS 6 (sans aucun réglage spécial comme avoir à poster manuellement des notifications).

Pour notre UITextField-scenario cela fonctionne très bien si vous ajoutez ce code à, par exemple, votre UIViewController qui contient le champ de texte:

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];

}

Crédit à cette réponse concernant la gestion "contextuelle": https://stackoverflow.com/a/12097161/2078512

Note: Semble que pendant que vous êtes dans le processus de éditer un UITextField Avec le clavier iOS intégré, la propriété "texte" du champ de texte n'est pas mise à jour avec chaque nouvelle lettre tapée / supprimée. Au lieu de cela, l'objet de champ de texte est mis à jour "dans son ensemble" après que vous ayez démissionné du statut de premier répondeur du champ de texte.


25
2018-02-19 17:07



Nous pouvons facilement configurer cela à partir de Storyboard, CTRL faites glisser le @IBAction et changez l'événement comme suit:

enter image description here


19
2017-08-22 09:30



Ici en version rapide pour les mêmes.

textField.addTarget(self, action: "textFieldDidChange:", forControlEvents: UIControlEvents.EditingChanged)

func textFieldDidChange(textField: UITextField) {

}

Merci


12
2017-10-01 07:02



J'ai résolu le problème en modifiant le comportement de shouldChangeChractersInRange. Si vous renvoyez NO, les modifications ne seront pas appliquées par iOS en interne, mais vous aurez la possibilité de les modifier manuellement et d'effectuer toute action après les modifications.

- (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
}

9
2017-11-11 15:30



Version rapide testée:

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

Paramètres expliqués:

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

Ensuite, ajoutez la méthode que vous avez créée ci-dessus dans votre UIViewController:

//Gets called everytime the text changes in the textfield.
func textFieldDidChange(textField: UITextField){

    print("Text changed: " + textField.text!)

}

8
2018-04-25 08:45



Pour Swift 3.0:

let textField = UITextField()

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

en utilisant la classe comme:

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

    }
}

4
2017-09-04 16:31



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!)

}

3
2017-11-08 01:24