UITextField文本更改事件

本文翻译自:UITextField text change event

How can I detect any text changes in a textField? 如何检测textField中的任何文本更改? The delegate method shouldChangeCharactersInRange works for something, but it did not fulfill my need exactly. 委托方法shouldChangeCharactersInRange可以为某些事情工作,但它不能完全满足我的需要。 Since until it returns YES, the textField texts are not available to other observer methods. 因为直到返回YES,否则textField文本不可用于其他观察者方法。

eg in my code calculateAndUpdateTextFields did not get the updated text, the user has typed. 例如,在我的代码中,用户已键入, calculateAndUpdateTextFields未获取更新的文本。

Is their any way to get something like textChanged Java event handler. 他们以任何方式获得诸如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;
}

#1楼

参考:https://stackoom.com/question/TPlL/UITextField文本更改事件


#2楼

XenElement's answer is spot on. XenElement的答案是正确的。

The above can be done in interface builder too by right-clicking on the UITextField and dragging the "Editing Changed" send event to your subclass unit. 右键单击UITextField并将“ Editing Changed”发送事件拖到您的子类单元中,也可以在界面生成器中完成上述操作。

UITextField更改事件


#3楼

As stated here: UITextField text change event , it seems that as of iOS 6 (iOS 6.0 and 6.1 checked) it is not possible to fully detect changes in UITextField objects just by observing the UITextFieldTextDidChangeNotification . 如此处所述: UITextField文本更改事件从iOS 6 (已检查iOS 6.0和6.1)开始,似乎无法仅通过观察UITextFieldTextDidChangeNotification来完全检测UITextField对象中的更改。

It seems that only those changes made directly by the built-in iOS keyboard are tracked now. 看来,现在仅跟踪由内置iOS键盘直接进行的那些更改。 This means that if you change your UITextField object just by invoking something like this: myUITextField.text = @"any_text" , you won't be notified about any changes at all. 这意味着,如果仅通过调用以下内容来更改UITextField对象: myUITextField.text = @"any_text" ,则根本不会收到有关任何更改的通知。

I don't know if this is a bug or it is intended. 我不知道这是错误还是故意的。 Seems like a bug since I haven't found any reasonable explanation in documentation. 似乎是一个错误,因为我没有在文档中找到任何合理的解释。 This is also stated here: UITextField text change event . 这里也说明了这一点: UITextField文本更改事件

My "solution" to this is to actually post a notification by myself for every change I make to my UITextField (if that change is done without using the built-in iOS keyboard). 我对此的“解决方案”是实际上对我对UITextField所做的每项更改(如果未使用内置iOS键盘进行更改)由我自己发布通知。 Something like this: 像这样:

myUITextField.text = @"I'm_updating_my_UITextField_directly_in_code";

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

[NSNotificationCenter.defaultCenter 
  postNotification:myTextFieldUpdateNotification];

This way you are 100% confident that you'll receive the same notification when you change the .text property of your UITextField object, either when you update it "manually" in your code or through the built-in iOS keyboard. 这样,当您在代码中“手动”更新或通过内置iOS键盘更改UITextField对象的.text属性时,您将100%确信会收到相同的通知。

It is important to consider that, since this is not a documented behavior, this approach may lead to 2 notifications received for the same change in your UITextField object. 重要的是要考虑到,由于这不是已记录的行为,因此此方法可能导致UITextField对象中的相同更改收到2条通知。 Depending on your needs (what you actually do when your UITextField.text changes) this could be an inconvenience for you. 根据您的需要( UITextField.text更改时的实际操作),这可能给您带来不便。

A slightly different approach would be to post a custom notification (this is, with a custom name other than UITextFieldTextDidChangeNotification ) if you actually need to know whether the notification was yours or "iOS-made". 如果您实际上需要知道该通知是您的还是“ iOS制造的”,则稍有不同的方法是发布自定义通知(即使用UITextFieldTextDidChangeNotification以外的其他自定义名称)。

EDIT: 编辑:

I've just found a different approach which I think could be better: 我刚刚发现了另一种我认为可能更好的方法:

This involves the Key-Value Observing (KVO) feature of Objective-C ( http://developer.apple.com/library/ios/#documentation/cocoa/conceptual/KeyValueObserving/KeyValueObserving.html#//apple_ref/doc/uid/10000177-BCICJDHA ). 这涉及到Objective-C的键值观察(KVO)功能( http://developer.apple.com/library/ios/#documentation/cocoa/conceptual/KeyValueObserving/KeyValueObserving.html#//apple_ref/doc/uid / 10000177-BCICJDHA )。

Basically, you register yourself as an observer of a property and if this property changes you get notified about it. 基本上,您将自己注册为某个属性的观察者,并且如果此属性发生更改,则会收到有关该属性的通知。 The "principle" is quite similar to how NSNotificationCenter works, being the main advantage that this approach works automatically also as of iOS 6 (without any special tweak like having to manually post notifications). “原理”与NSNotificationCenter工作原理非常相似,这是该方法从iOS 6起也自动运行的主要优点(无需进行任何特殊的调整,如必须手动发布通知)。

For our UITextField -scenario this works just fine if you add this code to, for example, your UIViewController that contains the text field: 对于我们的UITextField -scenario,如果将以下代码添加到例如包含文本字段的UIViewController ,则可以很好地工作:

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

}

Credit to this answer regarding "context" management: https://stackoverflow.com/a/12097161/2078512 归功于有关“上下文”管理的此答案: https : //stackoverflow.com/a/12097161/2078512

Note: Seems like while you are in the process of editing a UITextField with the built-in iOS keyboard, the "text" property of the text field is not updated with every new letter typed/removed. 注:好像当你编辑的过程中 UITextField与内置的iOS键盘,文本字段的“文本”属性不与每一个新的字母输入/删除更新。 Instead, the text field object gets updated "as a whole" after you resign the first responder status of the text field. 相反,在您退出文本字段的第一响应者状态后,文本字段对象将“作为一个整体”进行更新。


#4楼

to set the event listener: 设置事件监听器:

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

to actually listen: 实际听:

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

#5楼

I resolved the issue changing the behavior of shouldChangeChractersInRange. 我解决了更改shouldChangeChractersInRange行为的问题。 If you return NO the changes won't be applied by iOS internally, instead you have the opportunity to change it manually and perform any actions after the changes. 如果您返回NO,则更改将不会在内部由iOS内部应用,而是可以手动更改并在更改后执行任何操作。

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

#6楼

Here in swift version for same. 在这里为相同的快速版本。

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

func textFieldDidChange(textField: UITextField) {

}

Thanks 谢谢

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值