Changement de texte UITextField

Comment puis-je détecter tout changement de texte dans un champ de texte? La méthode du délégué shouldChangeCharactersInRange fonctionne pour quelque chose, mais elle ne répond pas exactement à mon besoin. Puisque jusqu'à ce qu'il retourne Oui, les textes de textField ne sont pas disponibles pour d'autres méthodes d'observateur.

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

est leur moyen d'obtenir quelque chose comme textChanged Java event handler.

- (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;
}
471
demandé sur Juan Boero 2011-08-10 16:09:41

19 réponses

à Partir de bonne façon de le faire uitextfield changement de texte call back :

j'attrape les caractères envoyés à un contrôle UITextField quelque chose comme ceci:

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

puis dans la méthode textFieldDidChange: vous pouvez examiner le contenu du champ text, et recharger votre vue de table si nécessaire.

vous pouvez utiliser ça et mettre calculateAndUpdateTextFields comme votre selector .

932
répondu Daniel G. Wilson 2017-02-21 04:37:52

la réponse de XenElement est évidente.

ce qui précède peut aussi être fait dans interface builder en cliquant avec le bouton droit de la souris sur L'UITextField et en faisant glisser l'événement" édition modifiée " à votre unité de sous-classe.

UITextField Change Event

345
répondu William T. 2015-12-10 15:51:10

pour définir l'auditeur de l'événement:

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

à vraiment écouter:

- (void)textFieldDidChange:(UITextField *)textField {
    NSLog(@"text changed: %@", textField.text);
}
117
répondu asdf 2018-03-19 21:53:24

Swift:

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

ensuite, implémenter la fonction de rappel:

@objc func textFieldDidChange(textField: UITextField){

print("Text changed")

}
59
répondu Juan Boero 2017-12-29 20:23:41

comme indiqué ici: UITextField text change event , il semble que à partir de iOS 6 (iOS 6.0 et 6.1 cochés) il n'est pas possible de détecter complètement les changements dans UITextField objets simplement en observant le UITextFieldTextDidChangeNotification .

il semble que seuls les changements effectués directement par le clavier iOS intégré soient repérés maintenant. Cela signifie que si vous changez votre objet UITextField simplement en invoquant quelque chose comme ceci: myUITextField.text = @"any_text" , vous ne serez pas informé de tout changement.

je ne sais pas si c'est un bug ou c'est prévu. Cela ressemble à un bogue puisque je n'ai trouvé aucune explication raisonnable dans la documentation. C'est aussi indiqué ici: UITextField changement de texte de l'événement .

ma "solution" à ceci est de poster réellement une notification par moi - même pour chaque changement que je fais à mon UITextField (si ce changement est fait sans utiliser le clavier iOS intégré). Quelque chose comme ceci:

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 changez la propriété .text de votre objet UITextField , que ce 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 objet UITextField . Selon vos besoins (ce que vous faites réellement lorsque votre UITextField.text change), cela pourrait être un inconvénient pour vous.

une approche légèrement différente serait de poster 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"iOS-made".

EDIT:

je viens de trouver un approche différente, qui je pense pourrait être mieux:

il s'agit de la Key-Value Observing (KVO) caractéristique de L'objectif-C ( http://developer.apple.com/library/ios/#documentation/cocoa/conceptual/KeyValueObserving/KeyValueObserving.html#//apple_ref/doc/uid/10000177-BCICJDHA ).

Fondamentalement, inscrivez-vous en tant qu'observateur de la propriété et si cette propriété les modifications que vous soyez informé à ce sujet. Le "principe "est tout à fait similaire à la façon dont NSNotificationCenter fonctionne, étant le principal avantage que cette approche fonctionne automatiquement aussi à partir de iOS 6 (sans aucun tweak spécial comme avoir à poster manuellement des notifications).

pour notre UITextField - scénario 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 gestion "contextuelle": https://stackoverflow.com/a/12097161/2078512

Note: semble comme pendant que vous êtes dans le processus de éditant 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 dactylographiée/enlevée. Au lieu de cela, l'objet text field est mis à jour "dans son ensemble" après avoir quitté le statut de premier intervenant du champ text.

25
répondu ercolemtar 2017-05-23 12:02:49

nous pouvons facilement configurer que de Storyboard , Ctrl faire glisser l'événement @IBAction et changer comme suit:

enter image description here

20
répondu bikram sapkota 2016-10-04 15:14:26

ici en version swift pour le même.

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

func textFieldDidChange(textField: UITextField) {

}

Merci

12
répondu Hindu 2015-10-01 07:02:12

j'ai résolu le problème en changeant le comportement de shouldChangeChractersInRange. Si vous ne retournez pas les modifications ne seront pas appliquées par iOS en interne, à la place vous avez la possibilité de les modifier manuellement et d'effectuer toutes les actions 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
répondu Pauls 2013-11-11 15:30:03

version Swift 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

puis 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
répondu rottenoats 2016-04-27 07:36:12

Pour Swift 3.0:

let textField = UITextField()

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

utilisant une classe comme:

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

    }
}
4
répondu pedrouan 2016-09-04 16:31:17

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
répondu sconewolf 2017-11-08 01:24:31

vous devriez utiliser la notification pour résoudre ce problème,parce que l'autre méthode écoutera la boîte de saisie pas la saisie réelle,surtout quand vous utilisez la méthode de saisie chinoise. In viewDidload

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

puis

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

}

enfin, tu cours, c'est fini.

2
répondu HsuChihYung 2016-04-25 06:42:25

Swift 3.1:

Selector: ClassName.MethodName

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

  func fieldChanged(textfieldChange: UITextField){

    }
2
répondu Beyaz 2017-04-11 11:32:34

avec fermeture:

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

    func targetSelector() {
        self.targetAction?()
    }
    }

et utilisant

textField.targetAction? = {
 // will fire on text changed
 }
2
répondu ebohdas 2017-06-21 14:46:15
[[NSNotificationCenter defaultCenter] addObserver:self 
selector:@selector(didChangeTextViewText:) 
name:UITextFieldTextDidChangeNotification object:nil];



- (void) didChangeTextViewText {
 //do something
}
1
répondu PeiweiChen 2016-01-04 06:57:28

Swift 3 Version:

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

   }

}

n'oubliez pas de placer le délégué.

1
répondu Joseph Francis 2017-06-06 02:36:35

Swift 3 Version

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

Et obtenir les changements ici

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

J'espère que ça aidera.

1
répondu Riajur Rahman 2017-12-04 06:58:12

c'est vraiment simple avec un swift observateur et réactif (rxcocoa & RxSwift).

il suffit de s'abonner à la propriété de texte de rx, comme ci-dessous:

myTextField.rx.text.subscribe { text in
   print("UITextFieldTextChangeEvent Text:\(text)")
}.disposed(by: disposeBag)
0
répondu SPatel 2018-06-30 05:23:11

Swift 3

@IBAction func textfildChange(sender: UITextField) {
        if let number = sender.text {
            if number.isEmpty {

            } else {
               print(number)
            }
        }
    }
-1
répondu Rob-4608 2017-12-06 05:49:06