web-dev-qa-db-ja.com

UITextFieldテキスト変更イベント

TextFieldでテキストの変更を検出する方法を教えてください。デリゲートメソッド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;
}
519
karim

uitextfieldのテキスト変更コールバックを行うための正しい方法から

UITextFieldコントロールに送信された文字は次のようになります。

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

Objective-Cでは:

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

Swiftでは:

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

それからtextFieldDidChangeメソッドでtextFieldの内容を調べ、必要に応じてテーブルビューをリロードします。

あなたはそれを使い、 calculateAndUpdateTextFields をあなたのselectorとして置くことができます。

979

XenElementの答えはその場です。

UITextFieldを右クリックして "Editing Changed"送信イベントをあなたのサブクラスユニットにドラッグすることで、インターフェースビルダーでも上記のことができます。

UITextField Change Event

364
William T.

イベントリスナを設定します。

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

実際に聞くために:

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

スイフト:

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

次に、コールバック関数を実装します。

@objc func textFieldDidChange(textField: UITextField){

print("Text changed")

}
74
Juan Boero

ここで述べたように、 ITextFieldテキスト変更イベントiOS 6の時点(iOS 6.0および6.1のチェック)では、UITextFieldオブジェクトの変更を完全に検出することはできませんUITextFieldTextDidChangeNotificationを観察します。

組み込みのiOSキーボードによって直接行われた変更のみが現在追跡されているようです。つまり、myUITextField.text = @"any_text"のような何かを呼び出すだけでUITextFieldオブジェクトを変更した場合、変更はまったく通知されません。

これがバグなのか、それとも意図的なものなのかわかりません。ドキュメントに合理的な説明が見つからないので、バグのようです。これもここに記載されています: ITextFieldテキスト変更イベント

これに対する私の「解決策」は、UITextFieldを変更するたびに、実際に自分で通知を投稿することです(組み込みのiOSキーボードを使用せずに変更を行う場合)。このようなもの:

myUITextField.text = @"I'm_updating_my_UITextField_directly_in_code";

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

[NSNotificationCenter.defaultCenter 
  postNotification:myTextFieldUpdateNotification];

これにより、コードで「手動で」更新するか、組み込みのiOSキーボードを使用して、UITextFieldオブジェクトの.textプロパティを変更したときに同じ通知を受け取ることを100%確信できます。

これは文書化された動作ではないため、この方法では、UITextFieldオブジェクトの同じ変更に対して2つの通知を受け取る可能性があることを考慮することが重要です。ニーズ(UITextField.textが変更されたときに実際に行うこと)によっては、これが不便になる場合があります。

通知が自分のものであるか「iOS製」であるかを実際に知る必要がある場合は、少し異なるアプローチでカスタム通知を投稿します(これはUITextFieldTextDidChangeNotification以外のカスタム名で)。

編集:

私はちょうど良いと思う別のアプローチを見つけました:

これには、Objective-Cの Key-Value Observing(KVO)機能が含まれます( 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://stackoverflow.com/a/12097161/2078512

注: /の組み込みiOSキーボードでUITextFieldを編集している間、テキストフィールドの「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の動作を変更する問題を解決しました。 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
}
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

スイフト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!)

}
5
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バージョン

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

それが役に立てば幸い。

3
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

スウィフト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