UITextField text change event
如何检测文本字段中的任何文本更改?委托方法
例如,在我的代码
是他们获取EDCOX1,2,Java事件处理程序的方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | - (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; } |
从正确的方式执行uitextfield文本更改回拨:
I catch the characters sent to a UITextField control something like this:
1 | // Add a"textFieldDidChange" notification method to the text field control. |
在Objul-C中:
1 2 3 | [textField addTarget:self action:@selector(textFieldDidChange:) forControlEvents:UIControlEventEditingChanged]; |
在SWIFT中:
1 | textField.addTarget(self, action: #selector(textFieldDidChange), for: .editingChanged) |
Then in the
textFieldDidChange method you can examine the contents of the textField, and reload your table view as needed.
您可以使用它并将CalculateAndUpdateTextFields作为您的
Xenelement的答案是"当场"。
在Interface Builder中,也可以通过右键单击uitextfield并将"编辑已更改"发送事件拖动到子类单元来完成上述操作。
要设置事件侦听器:
1 | [self.textField addTarget:self action:@selector(textFieldDidChange:) forControlEvents:UIControlEventEditingChanged]; |
要真正倾听:
1 2 3 | - (void)textFieldDidChange:(UITextField *)textField { NSLog(@"text changed: %@", textField.text); } |
Swift:
1 | yourTextfield.addTarget(self, action: #selector(textFieldDidChange(textField:)), for: .editingChanged) |
然后,实现回调函数:
1 2 3 4 5 | @objc func textFieldDidChange(textField: UITextField){ print("Text changed") } |
如前所述:uitextfield文本更改事件,似乎在iOS 6(iOS 6.0和6.1已检查)中,仅通过观察
现在似乎只跟踪那些由内置iOS键盘直接进行的更改。这意味着,如果您仅仅通过调用这样的东西来更改您的
我不知道这是一个bug还是有意的。似乎是个错误,因为我在文档中没有找到任何合理的解释。这里也说明了这一点:uitextfield文本更改事件。
我对此的"解决方案"是,实际上将我所做的每一个更改都由我自己发布一个通知给我的
1 2 3 4 5 6 7 8 | myUITextField.text = @"I'm_updating_my_UITextField_directly_in_code"; NSNotification *myTextFieldUpdateNotification = [NSNotification notificationWithName:UITextFieldTextDidChangeNotification object:myUITextField]; [NSNotificationCenter.defaultCenter postNotification:myTextFieldUpdateNotification]; |
这样,无论您是在代码中"手动"更新还是通过内置的iOS键盘,当您更改
重要的是要考虑到,由于这不是一种记录在案的行为,因此这种方法可能会导致为您的
稍有不同的方法是发布自定义通知(这是一个自定义名称,而不是
编辑:
我刚刚找到了一种我认为更好的方法:
这涉及到Objective-C的关键值观察(kvo)功能(http://developer.apple.com/library/ios/documentation/cocoa/conceptive/keyValueObservation/keyValueObservation.html//apple-ref/doc/uid/1000017-bcicjdha)。
基本上,您将自己注册为一个属性的观察者,如果这个属性发生了变化,您将得到关于它的通知。"原则"与
对于我们的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | 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]; } |
关于"上下文"管理的回答值得信赖:https://stackoverflow.com/a/12097161/2078512
注意:似乎在使用内置iOS键盘编辑
我们可以很容易地从
这里有一个同样的Swift版本。
1 2 3 4 5 | textField.addTarget(self, action:"textFieldDidChange:", forControlEvents: UIControlEvents.EditingChanged) func textFieldDidChange(textField: UITextField) { } |
谢谢
我解决了改变shouldchangechractersinrange行为的问题。如果返回"否",则iOS不会在内部应用更改,而是有机会手动更改更改,并在更改后执行任何操作。
1 2 3 4 5 6 7 | - (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版本:
1 2 3 4 5 6 | //Somewhere in your UIViewController, like viewDidLoad(){ ... } self.textField.addTarget( self, action: #selector(SearchViewController.textFieldDidChange(_:)), forControlEvents: UIControlEvents.EditingChanged ) |
参数说明:
1 2 3 | 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 |
然后在您的
1 2 3 4 5 6 | //Gets called everytime the text changes in the textfield. func textFieldDidChange(textField: UITextField){ print("Text changed:" + textField.text!) } |
斯威夫特3:
1 2 3 4 5 6 7 | let textField = UITextField() textField.addTarget( nil, action: #selector(MyClass.textChanged(_:)), for: UIControlEvents.editingChanged ) |
使用类如:
1 2 3 4 5 | class MyClass { func textChanged(sender: Any!) { } } |
斯威夫特4
1 2 3 4 5 6 7 8 9 10 11 12 | 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版
1 | yourTextField.addTarget(self, action: #selector(YourControllerName.textChanges(_:)), for: UIControlEvents.editingChanged) |
把零钱拿进来
1 2 3 4 | func textChanges(_ textField: UITextField) { let text = textField.text! // your desired text here // Now do whatever you want. } |
希望它有帮助。
斯威夫特3.1:
Selector: ClassName.MethodName
1 2 3 4 5 | cell.lblItem.addTarget(self, action: #selector(NewListScreen.fieldChanged(textfieldChange:)), for: .editingChanged) func fieldChanged(textfieldChange: UITextField){ } |
关闭:
1 2 3 4 5 6 7 8 9 10 11 | class TextFieldWithClosure: UITextField { var targetAction: (() -> Void)? { didSet { self.addTarget(self, action: #selector(self.targetSelector), for: .editingChanged) } } func targetSelector() { self.targetAction?() } } |
并使用
1 2 3 | textField.targetAction? = { // will fire on text changed } |
您应该使用通知来解决这个问题,因为另一个方法会监听输入框而不是实际输入,特别是当您使用中文输入法时。在视图加载中
1 2 3 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textFiledEditChanged:) name:@"UITextFieldTextDidChangeNotification" object:youTarget]; |
然后
1 2 3 4 5 6 7 8 9 10 11 12 | - (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; } |
}
最后,你跑,会成功的。
1 2 3 4 5 6 7 8 9 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didChangeTextViewText:) name:UITextFieldTextDidChangeNotification object:nil]; - (void) didChangeTextViewText { //do something } |
Swift 3版本:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | 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 } } |
别忘了设置委托。
斯威夫特4版
利用关键值观察通知对象有关其他对象属性的更改。
1 2 3 4 5 6 | var textFieldObserver: NSKeyValueObservation? textFieldObserver = yourTextField.observe(\.text, options: [.new, .old]) { [weak self] (object, changeValue) in guard let strongSelf = self else { return } print(changeValue) } |
观察者和反应式swift(rxcococa&rxswift)非常简单。
只需订阅RX的文本属性,如下所示:
1 2 3 | myTextField.rx.text.subscribe { text in print("UITextFieldTextChangeEvent Text:\(text)") }.disposed(by: disposeBag) |