ios did - Событие изменения текста UITextField




change swift (16)

Как я могу обнаружить любые текстовые изменения в текстовом поле? Метод delegate shouldChangeCharactersInRange работает для чего-то, но он точно не соответствует моей потребности. Поскольку до тех пор, пока он не вернет YES, тексты textField недоступны другим методам наблюдения.

например, в моем коде calculateAndUpdateTextFields не получил обновленный текст, пользователь набрал.

Это их способ получить что-то вроде 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;
}

Answers

Быстрая версия:

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

Параметры объяснены:

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

Затем добавьте метод, который вы создали выше, в свой UIViewController :

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

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

}

Для Swift 3.0:

let textField = UITextField()

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

используя класс:

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

    }
}

Swift 3 Версия:

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

   }

}

Не забудьте установить делегат.


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

}

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



- (void) didChangeTextViewText {
 //do something
}

Мы можем легко настроить это из Storyboard , CTRL перетащить @IBAction и change следующим образом:


Вы должны использовать уведомление для решения этой проблемы, потому что другой метод будет слушать поле ввода, а не на самом деле, особенно если вы используете китайский метод ввода. В viewDidload

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

затем

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

}

наконец, вы бежите, сделаете.


Swift 3.1:

Селектор: ClassName.MethodName

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

  func fieldChanged(textfieldChange: UITextField){

    }

Это очень просто с наблюдателем и реактивным быстрым (RxCocoa & RxSwift).

Просто подпишитесь на текстовое свойство rx, как показано ниже:

myTextField.rx.text.subscribe { text in
   print("UITextFieldTextChangeEvent Text:\(text)")
}.disposed(by: disposeBag)

Я решил проблему изменения поведения shouldChangeChractersInRange. Если вы вернетесь НЕТ, изменения не будут применяться 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
}

для установки прослушивателя событий:

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

на самом деле слушать:

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

Swift:

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

Затем выполните функцию обратного вызова:

@objc func textFieldDidChange(textField: UITextField){

print("Text changed")

}

Ответ XenElement - это место.

Вышеупомянутое может быть сделано в построителе интерфейса, щелкнув правой кнопкой мыши по UITextField и перетащив событие отправки «Редактирование изменено» в ваш блок подкласса.


Как указано здесь: событие изменения текста UITextField , похоже, что с iOS 6 (iOS 6.0 и 6.1 проверено) невозможно полностью обнаружить изменения в объектах UITextField просто наблюдая за UITextFieldTextDidChangeNotification .

Кажется, что только те изменения, внесенные непосредственно встроенной клавиатурой iOS, теперь отслеживаются. Это означает, что если вы измените свой объект UITextField просто вызвав что-то вроде этого: myUITextField.text = @"any_text" , вы не будете уведомлены о каких-либо изменениях вообще.

Я не знаю, является ли это ошибкой или она предназначена. Похоже на ошибку, поскольку я не нашел разумного объяснения в документации. Это также указано здесь: событие изменения текста UITextField .

Мое «решение» заключается в том, чтобы на самом деле публиковать уведомление для каждого изменения, которое я делаю для своего UITextField (если это изменение выполняется без использования встроенной клавиатуры iOS). Что-то вроде этого:

myUITextField.text = @"I'm_updating_my_UITextField_directly_in_code";

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

[NSNotificationCenter.defaultCenter 
  postNotification:myTextFieldUpdateNotification];

Таким образом, вы на 100% уверены, что получите такое же уведомление при изменении свойства .text вашего объекта UITextField , либо при его обновлении «вручную» в вашем коде, либо через встроенную клавиатуру iOS.

Важно учитывать, что, поскольку это не документированное поведение, этот подход может привести к 2 уведомлениям, полученным для того же изменения в вашем объекте UITextField . В зависимости от ваших потребностей (что вы на самом деле делаете при изменении UITextField.text ) это может быть неудобно для вас.

Несколько иной подход состоял бы в том, чтобы опубликовать пользовательское уведомление (то есть с пользовательским именем, отличным от UITextFieldTextDidChangeNotification ), если вам действительно нужно знать, было ли ваше уведомление или «сделано iOS».

РЕДАКТИРОВАТЬ:

Я только что нашел другой подход, который, я думаю, может быть лучше:

Это включает в себя функцию Key-Value Observing (KVO) Objective-C ( http://developer.apple.com/library/ios/#documentation/cocoa/conceptual/KeyValueObserving/KeyValueObserving.html#//apple_ref/doc/uid/10000177-BCICJDHA ).

В принципе, вы регистрируетесь как наблюдатель свойства, и если это свойство изменяется, вы получите уведомление об этом. «Принцип» очень похож на работу NSNotificationCenter , являясь основным преимуществом, что этот подход работает автоматически также с iOS 6 (без каких-либо специальных настроек, например, для отправки уведомлений вручную).

Для нашего 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];

}

Подтвердите этот ответ относительно управления «контекстом»: https://.com/a/12097161/2078512

Примечание. Похоже, что пока вы находитесь в процессе редактирования UITextField со встроенной клавиатурой iOS, свойство «text» текстового поля не обновляется с каждой новой буквой, напечатанной / удаленной. Вместо этого объект текстового поля обновляется «в целом» после того, как вы отмените статус первого ответчика текстового поля.


От правильного пути, чтобы сделать изменение текста в тексте uitextfield :

Я улавлю персонажей, отправленных в UITextField, что-то вроде этого:

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

Затем в методе textFieldDidChange: вы можете проверить содержимое текстового поля и при необходимости обновить представление таблицы.

Вы можете использовать это и поместить calculateAndUpdateTextFields в качестве своего selector .


Быстро :

let fileURL = URL(fileURLWithPath: somepath)




ios objective-c swift event-handling uitextfielddelegate