it-swarm.com.ru

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

Как я могу обнаружить любые изменения текста в textField? Метод делегата shouldChangeCharactersInRange для чего-то работает, но он точно не удовлетворяет мою потребность. Так как, пока это не возвращает ДА, тексты 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;
}
529
karim

From правильный способ переопределения текста в uitextfield, обратный вызов :

Я ловлю символы, отправленные в элемент управления UITextField, примерно так:

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

В Objective-C:

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

В Свифте:

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

Затем в методе textFieldDidChange вы можете просмотреть содержимое textField и перезагрузить табличное представление по мере необходимости.

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

988
Daniel G. Wilson

Ответ XenElement точен.

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

UITextField Change Event

366
William T.

установить слушателя события:

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

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

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

Swift:

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

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

@objc func textFieldDidChange(textField: UITextField){

print("Text changed")

}
75
Juan Boero

Как указано здесь: событие изменения текста 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".

EDIT:

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

Это включает Наблюдение значения ключа (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- это прекрасно работает, если вы добавите этот код, например, в ваше 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://stackoverflow.com/a/12097161/2078512

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

28
ercolemtar

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

enter image description here

23
bikram sapkota

Здесь в Swift версия для того же.

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

func textFieldDidChange(textField: UITextField) {

}

Спасибо

13
Hindu

Я решил проблему, изменив поведение 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
}
10
Pauls

протестированная версия Swift:

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

}
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

Для Swift 3.0:

let textField = UITextField()

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

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

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

    }
}
5
pedrouan

Swift 3 Version

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

И получить изменения здесь

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

Надеюсь, поможет.

4
Riajur Rahman

Вы должны использовать уведомление для решения этой проблемы, потому что другой метод будет прослушивать поле ввода, а не фактический ввод, особенно когда вы используете китайский метод ввода. В 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;
} 

}

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

2
HsuChihYung

Swift 3.1:

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

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

  func fieldChanged(textfieldChange: UITextField){

    }
2
Beyaz

С закрытием:

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

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

и используя

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

Версия 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

   }

}

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

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



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

Версия Swift 4

Использование наблюдения значения ключа Уведомлять объекты об изменениях свойств других объектов.

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