611

textField 内のテキストの変更を検出するにはどうすればよいですか? デリゲート メソッドshouldChangeCharactersInRangeは何らかの目的で機能しますが、私のニーズを正確に満たすものではありませんでした。YES が返されるまで、textField のテキストは他のオブザーバー メソッドで使用できません。

たとえば、私のコードでcalculateAndUpdateTextFieldsは更新されたテキストを取得できませんでした。ユーザーが入力しました。

textChangedJavaイベントハンドラーのようなものを取得する方法はありますか?

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

22 に答える 22

1131

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 の内容を調べ、必要に応じてテーブル ビューをリロードします。

それを使用して、calculateAndUpdateTextFieldsselector.

于 2011-08-10T12:21:10.383 に答える
411

XenElement の答えは的を射ています。

上記は、UITextField を右クリックし、「Editing Changed」送信イベントをサブクラス ユニットにドラッグすることで、インターフェイス ビルダーでも実行できます。

UITextField 変更イベント

于 2012-12-05T17:36:14.933 に答える
140

イベントリスナーを設定するには:

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

実際に聞くには:

- (void)textFieldDidChange:(UITextField *)textField {
    NSLog(@"text changed: %@", textField.text);
}
于 2013-06-06T08:25:17.903 に答える
107

迅速:

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

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

@objc final private func yourHandler(textField: UITextField) {
    print("Text changed")
}
于 2016-03-14T22:00:28.163 に答える
32

ここで述べたように:UITextFieldテキスト変更イベントiOS 6UITextField (iOS 6.0および6.1がチェックされている)の時点では、を観察するだけではオブジェクトの変更を完全に検出することはできないよう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];

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

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

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

編集:

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

これには、Objective-Cのキー値監視(KVO)機能が含まれます( 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

注:組み込みのiOSキーボードを使用して編集しUITextFieldているときに、テキストフィールドの「text」プロパティが新しい文字を入力/削除するたびに更新されるわけではないようです。代わりに、テキストフィールドのファーストレスポンダーステータスを辞任した後、テキストフィールドオブジェクトは「全体として」更新されます。

于 2013-02-19T17:07:59.240 に答える
29

から簡単に設定できますStoryboard。CTRL キーを押しながらドラッグし、@IBAction次のようにイベントを変更します。

ここに画像の説明を入力

于 2016-08-22T09:30:17.460 に答える
15

ここでは、同じバージョンの迅速なバージョンです。

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

func textFieldDidChange(textField: UITextField) {

}

ありがとう

于 2015-10-01T07:02:12.873 に答える
11

Swift Version tested:

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

Parameters explained:

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

Then add the method you created above in your UIViewController:

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

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

}
于 2016-04-25T08:45:10.433 に答える
8

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

}
于 2017-11-08T01:24:31.927 に答える
5

スウィフト 3.0 の場合:

let textField = UITextField()

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

次のようなクラスを使用します。

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

    }
}
于 2016-09-04T16:31:17.540 に答える
4

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

それが役に立てば幸い。

于 2017-12-04T06:58:12.550 に答える
2

特に中国語の入力方法を使用する場合、他の方法は実際の入力ではなく入力ボックスをリッスンするため、この問題を解決するには通知を使用する必要があります。ビューでDidload

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

}

最後に、実行します。

于 2016-04-25T06:42:25.840 に答える