wake-up-neo.com

UITextField-Textänderungsereignis

Wie kann ich Textänderungen in einem textField erkennen? Die Delegate-Methode shouldChangeCharactersInRange funktioniert für etwas, hat aber mein Bedürfnis nicht genau erfüllt. Da die textField-Texte für andere Observer-Methoden nicht verfügbar sind, bis JA zurückgegeben wird.

z.B. In meinem Code calculateAndUpdateTextFields hat der Benutzer den aktualisierten Text nicht erhalten.

Gibt es eine Möglichkeit, so etwas wie textChanged Java Event-Handler zu bekommen.

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

Von richtiger Weg, um einen Textänderungsrückruf für uitextfield durchzuführen :

Ich fange die Zeichen ab, die an ein UITextField-Steuerelement gesendet wurden:

// Add a "textFieldDidChange" notification method to the text field control.

In Ziel-C:

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

In Swift:

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

Anschließend können Sie in der textFieldDidChange -Methode den Inhalt von textField überprüfen und Ihre Tabellenansicht nach Bedarf neu laden.

Sie könnten das verwenden und berechneAndUpdateTextFields als Ihr selector eingeben.

1004

Die Antwort von XenElement ist genau richtig.

Dies kann auch im Interface Builder geschehen, indem Sie mit der rechten Maustaste auf das UITextField klicken und das Sendeereignis "Editing Changed" auf Ihre Unterklasseneinheit ziehen.

UITextField Change Event

373
William T.

so legen Sie den Ereignis-Listener fest:

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

um tatsächlich zuzuhören:

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

Swift:

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

Implementieren Sie dann die Rückruffunktion:

@objc func textFieldDidChange(textField: UITextField){

print("Text changed")

}
77
Juan Boero

Wie hier angegeben: ITextField-Textänderungsereignis , es scheint, dass ab iOS 6 (iOS 6.0 und 6.1 aktiviert) es ist Änderungen an UITextField Objekten können nur durch Beobachten von UITextFieldTextDidChangeNotification nicht vollständig erkannt werden.

Es scheint, dass nur die Änderungen, die direkt über die integrierte iOS-Tastatur vorgenommen wurden, jetzt nachverfolgt werden. Das heißt, wenn Sie Ihr UITextField -Objekt ändern, indem Sie einfach Folgendes aufrufen: myUITextField.text = @"any_text", werden Sie überhaupt nicht über Änderungen benachrichtigt.

Ich weiß nicht, ob dies ein Fehler ist oder beabsichtigt ist. Scheint ein Fehler zu sein, da ich in der Dokumentation keine vernünftige Erklärung gefunden habe. Dies wird auch hier angegeben: ITextField-Textänderungsereignis .

Meine "Lösung" besteht darin, für jede Änderung, die ich an meinem UITextField vornehme, eine Benachrichtigung von mir selbst zu senden (wenn diese Änderung ohne Verwendung der integrierten iOS-Tastatur vorgenommen wird). Etwas wie das:

myUITextField.text = @"I'm_updating_my_UITextField_directly_in_code";

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

[NSNotificationCenter.defaultCenter 
  postNotification:myTextFieldUpdateNotification];

Auf diese Weise sind Sie zu 100% sicher, dass Sie dieselbe Benachrichtigung erhalten, wenn Sie die Eigenschaft .text Ihres UITextField -Objekts ändern, entweder wenn Sie es "manuell" in Ihrem Code aktualisieren oder über die integrierte in iOS-Tastatur.

Da dies kein dokumentiertes Verhalten ist, muss berücksichtigt werden, dass dieser Ansatz möglicherweise zu zwei Benachrichtigungen für dieselbe Änderung in Ihrem UITextField -Objekt führt. Abhängig von Ihren Bedürfnissen (was Sie tatsächlich tun, wenn sich Ihr UITextField.text ändert) kann dies eine Unannehmlichkeit für Sie sein.

Ein etwas anderer Ansatz wäre, eine benutzerdefinierte Benachrichtigung zu veröffentlichen (dies ist, mit einem anderen benutzerdefinierten Namen als UITextFieldTextDidChangeNotification), wenn Sie tatsächlich wissen müssen, ob die Benachrichtigung Ihre oder "iOS-made" war.

EDIT:

Ich habe gerade einen anderen Ansatz gefunden, der meiner Meinung nach besser sein könnte:

Dies beinhaltet die Schlüsselwertbeobachtung (KVO) Funktion von Objective-C ( http://developer.Apple.com/library/ios/#documentation/cocoa/conceptual/KeyValueObserving/KeyValueObserving.html#//Apple_ref/doc/uid/10000177-BCICJDHA ).

Grundsätzlich registrieren Sie sich als Beobachter einer Immobilie und werden benachrichtigt, wenn sich diese Immobilie ändert. Das "Prinzip" ist der Funktionsweise von NSNotificationCenter sehr ähnlich. Der Hauptvorteil besteht darin, dass dieser Ansatz auch ab iOS 6 automatisch funktioniert (ohne besondere Anpassungen, wie das manuelle Posten von Benachrichtigungen).

In unserem Szenario UITextField funktioniert dies einwandfrei, wenn Sie diesen Code beispielsweise zu Ihrem UIViewController hinzufügen, das das Textfeld enthält:

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

}

Wir danken dieser Antwort in Bezug auf "Kontext" -Verwaltung: https://stackoverflow.com/a/12097161/2078512

Hinweis: Während Sie mit der integrierten iOS-Tastatur ein UITextField bearbeiten , wird anscheinend die Eigenschaft "text" des Textfelds nicht aktualisiert mit jedem neuen Buchstaben getippt/entfernt. Stattdessen wird das Textfeldobjekt "als Ganzes" aktualisiert, nachdem Sie den Ersthelferstatus des Textfelds aufgegeben haben.

28
ercolemtar

Wir können das einfach über Storyboard konfigurieren, bei gedrückter STRG-Taste den @IBAction ziehen und das Ereignis wie folgt ändern:

enter image description here

25
bikram sapkota

Hier in Swift Version dafür.

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

func textFieldDidChange(textField: UITextField) {

}

Vielen Dank

13
Hindu

Ich habe das Problem behoben, bei dem das Verhalten von shouldChangeChractersInRange geändert wurde. Wenn Sie NEIN zurückgeben, werden die Änderungen von iOS nicht intern übernommen. Stattdessen haben Sie die Möglichkeit, sie manuell zu ändern und nach den Änderungen Aktionen auszuführen.

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

Swift Version getestet:

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

Parameter erklärt:

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

Fügen Sie dann die oben erstellte Methode in Ihrem UIViewController hinzu:

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

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

}
10
kemicofa

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

}
6
hgale

Für Swift 3.0:

let textField = UITextField()

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

mit klasse wie:

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

    }
}
5
pedrouan

Swift 3 Version

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

Und nimm die Änderungen hier

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

Ich hoffe es hilft.

4
Riajur Rahman

Sie sollten die Benachrichtigung verwenden, um dieses Problem zu beheben, da die andere Methode das Eingabefeld abhört und nicht die tatsächliche Eingabe, insbesondere wenn Sie die chinesische Eingabemethode verwenden. In viewDidload

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

dann

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

}

endlich rennst du, fertig.

2
HsuChihYung

Swift 3.1:

Auswahl: ClassName.MethodName

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

  func fieldChanged(textfieldChange: UITextField){

    }
2
Beyaz

Mit Verschluss:

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

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

und mit

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

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

   }

}

Vergessen Sie nicht, den Delegierten einzustellen.

1
Joseph Francis
[[NSNotificationCenter defaultCenter] addObserver:self 
selector:@selector(didChangeTextViewText:) 
name:UITextFieldTextDidChangeNotification object:nil];



- (void) didChangeTextViewText {
 //do something
}
1
PeiweiChen

Swift 4 Version

Verwenden der Schlüsselwertüberwachung Objekte über Änderungen an den Eigenschaften anderer Objekte benachrichtigen.

var textFieldObserver: NSKeyValueObservation?

textFieldObserver = yourTextField.observe(\.text, options: [.new, .old]) { [weak self] (object, changeValue) in
  guard let strongSelf = self else { return }
  print(changeValue)
}
0
Valeriy