UITextField text change event

后端 未结 21 1004
南方客
南方客 2020-11-22 06:49

How can I detect any text changes in a textField? The delegate method shouldChangeCharactersInRange works for something, but it did not fulfill my need exactly.

相关标签:
21条回答
  • 2020-11-22 07:24

    Swift 3.1:

    Selector: ClassName.MethodName

      cell.lblItem.addTarget(self, action: #selector(NewListScreen.fieldChanged(textfieldChange:)), for: .editingChanged)
    
      func fieldChanged(textfieldChange: UITextField){
    
        }
    
    0 讨论(0)
  • 2020-11-22 07:25

    We can easily configure that from Storyboard, CTRL drag the @IBAction and change event as following:

    0 讨论(0)
  • 2020-11-22 07:30

    From proper way to do uitextfield text change call back:

    I catch the characters sent to a UITextField control something like this:

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

    In Objective-C:

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

    In Swift:

    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.

    You could use that and put calculateAndUpdateTextFields as your selector.

    0 讨论(0)
  • 2020-11-22 07:31
    1. KVO solutions do not work

    KVO does NOT work in iOS for controls: http://stackoverflow.com/a/6352525/1402846 https://developer.apple.com/library/archive/documentation/General/Conceptual/DevPedia-CocoaCore/KVO.html

    1. In the observing class, you do this:

    Given that you know the text view you want to watch:

    var watchedTextView: UITextView!
    

    Do this:

    NotificationCenter.default.addObserver(
        self,
        selector: #selector(changed),
        name: UITextView.textDidChangeNotification,
        object: watchedTextView)
    

    However, be careful with that:

    • it's likely you only want to call that once, so do not call it in, for example, layoutSubviews

    • it's quite difficult to know when to best call it during your bring-up process. It will depend on your situation. Unfortunately there is no standard, locked-in solution

    • for example you usually certainly can not call it at init time, since of course watchedTextView may not exist yet

    .

    1. the next problem is that ...

    None of the notifications are called when text is changed programmatically.

    This is a huge, age-old, and stupid, nuisance in iOS engineering.

    Controls simply do not - end of story - call the notifcations when the .text property is changed programmatically.

    This is insanely annoying because of course - obviously - every app ever made sets the text programmatically, such as clearing the field after the user posts, etc.

    You have to subclass the text view (or similar control) like this:

    class NonIdioticTextView: UIITextView {
    
        override var text: String! {
            // boilerplate code needed to make watchers work properly:
            get {
                return super.text
            }
            set {
                super.text = newValue
                NotificationCenter.default.post(
                    name: UITextView.textDidChangeNotification,
                    object: self)
            }
    
        }
    
    }
    

    (Tip - don't forget the super call has to come before ! the post call.)

    There is no solution available, unless, you fix the control by subclassing as shown just above. That is the only solution.

    Note that the notification

    UITextView.textDidChangeNotification
    

    results in

    func textViewDidChangeSelection(_ textView: UITextView) 
    

    being called.

    (Not textViewDidChange .)

    0 讨论(0)
  • 2020-11-22 07:32

    Here in swift version for same.

    textField.addTarget(self, action: "textFieldDidChange:", forControlEvents: UIControlEvents.EditingChanged)
    
    func textFieldDidChange(textField: UITextField) {
    
    }
    

    Thanks

    0 讨论(0)
  • 2020-11-22 07:32

    I resolved the issue changing the behavior of 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.

    - (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
    }
    
    0 讨论(0)
提交回复
热议问题