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;
}
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
として置くことができます。
XenElementの答えはその場です。
UITextFieldを右クリックして "Editing Changed"送信イベントをあなたのサブクラスユニットにドラッグすることで、インターフェースビルダーでも上記のことができます。
イベントリスナを設定します。
[self.textField addTarget:self action:@selector(textFieldDidChange:) forControlEvents:UIControlEventEditingChanged];
実際に聞くために:
- (void)textFieldDidChange:(UITextField *)textField {
NSLog(@"text changed: %@", textField.text);
}
スイフト:
yourTextfield.addTarget(self, action: #selector(textFieldDidChange(textField:)), for: .editingChanged)
次に、コールバック関数を実装します。
@objc func textFieldDidChange(textField: UITextField){
print("Text changed")
}
ここで述べたように、 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」プロパティは新しい文字が入力されるたびに更新されないようです/削除されました。代わりに、テキストフィールドの最初のレスポンダーステータスを辞任すると、テキストフィールドオブジェクトが「全体として」更新されます。
これはSwift版でも同じです。
textField.addTarget(self, action: "textFieldDidChange:", forControlEvents: UIControlEvents.EditingChanged)
func textFieldDidChange(textField: UITextField) {
}
ありがとう
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
}
テストされた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!)
}
スイフト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!)
}
Swift 3.0の場合:
let textField = UITextField()
textField.addTarget(
nil,
action: #selector(MyClass.textChanged(_:)),
for: UIControlEvents.editingChanged
)
以下のようなクラスを使用します。
class MyClass {
func textChanged(sender: Any!) {
}
}
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.
}
それが役に立てば幸い。
この問題を解決するには、通知を使用する必要があります。他の方法では、特に中国語の入力方法を使用する場合は、実際の入力ではなく入力ボックスを監視するためです。 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){
}
クロージャー付き
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
}
スウィフト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
}
}
デリゲートを設定することを忘れないでください。
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(didChangeTextViewText:)
name:UITextFieldTextDidChangeNotification object:nil];
- (void) didChangeTextViewText {
//do something
}
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)
}