`textField:shouldChangeCharactersInRange:`を使用して、現在入力されている文字を含むテキストを取得するにはどうすればよいですか?


116

以下のコードを使用して、ユーザーが入力するたびにtextField2のテキストコンテンツをのテキストコンテンツと一致するように更新しtextField1ていますtextField1

- (BOOL) textField: (UITextField *)theTextField shouldChangeCharactersInRange: (NSRange)range replacementString: (NSString *)string {    
  if (theTextField == textField1){    
     [textField2 setText:[textField1 text]];    
  }
}

しかし、私が観察する出力はそれです...

textField1が「123」の場合、textField2は「12」です。

textField1が「1234」の場合、textField2は「123」です。

...私が欲しいのは:

textField1が「123」の場合、textField2は「123」です。

textField1が「1234」の場合、textField2は「1234」です。

何が悪いのですか?


8
思い出させるだけですが、"Editing Changed"イベントを常に使用するのは驚くほど簡単です。作成した関数にIBでドラッグするだけです。
Fattie

編集変更イベントは、自動修正/オートコンプリート/テキスト置換など、プログラムで生成されたテキスト変更イベントをキャプチャしません。
シム

回答:


272

-shouldChangeCharactersInRangeテキストフィールドが実際テキストを変更するに呼び出されます。そのため、古いテキスト値を取得しています。更新後にテキストを取得するには、以下を使用します。

[textField2 setText:[textField1.text stringByReplacingCharactersInRange:range withString:string]];

15
これはほとんど私にとってはうまくいきました。私が文字を入力した場合、これはうまくいきました。削除ボタンを押すと、2文字削除されます。私にとって、次の提案が機能しました:stackoverflow.com/questions/388237/… 基本的に、UITextFieldからコードにドラッグアンドドロップし(関数を作成するため)、次にTextFieldを右クリックしてドラッグします「編集が変更されました」のサークルから新しい機能にドロップします。(ため息
。VisualStudioに

これも有効な答えだと思いますが、THEの答えではありません。あなたが望むものを達成するための最良の方法は、@ tomuteによって答えられました
Pedro Borges

5
または、textFiel.text =(textFiel.text as NSString).stringByReplacingCharactersInRange(range、withString:string)in Swift
Max

@MikeGledhill同じことをプログラムで実行できます:[textField addTarget:self action:@selector(textFieldEditingChanged:) forControlEvents:UIControlEventEditingChanged]
Steve Moser

52
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
    NSString * searchStr = [textField.text stringByReplacingCharactersInRange:range withString:string];

    NSLog(@"%@",searchStr);
    return YES;
}

40

スウィフト3

受け入れられた回答に基づいて、以下はSwift 3で機能するはずです:

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {

    let newString = NSString(string: textField.text!).replacingCharacters(in: range, with: string)

    return true
}

注意

どちらStringNSString呼ばれる方法がありますreplacingCharacters:inRange:withString。ただし、予想通り、前者はのインスタンスをRange期待し、後者はのインスタンスを期待しますNSRangetextFieldデリゲートメソッドは、使用するNSRangeインスタンス、の従って使用NSStringこの場合は。


replacingCharactersする必要がありますstringByReplacingCharactersInRange
アラン・スカルパ2016年

1
@Alan_s私はこのコードをXcodeプロジェクトから直接コピーしましたが、問題なく動作していました。iOS 10.1のターゲットでXcode 8.1を使用していますか?
focorner 2016年


13

Swift(4)では、NSString(純粋なSwift)なし:

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {

    if let textFieldString = textField.text, let swtRange = Range(range, in: textFieldString) {

        let fullString = textFieldString.replacingCharacters(in: swtRange, with: string)

        print("FullString: \(fullString)")
    }

    return true
}

拡張として:

extension UITextField {

    func fullTextWith(range: NSRange, replacementString: String) -> String? {

        if let fullSearchString = self.text, let swtRange = Range(range, in: fullSearchString) {

            return fullSearchString.replacingCharacters(in: swtRange, with: replacementString)
        }

        return nil
    }
}

// Usage:

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {

    if let textFieldString = textField.fullTextWith(range: range, replacementString: string) {
        print("FullString: \(textFieldString)")
    }

    return true
}

8

それのスウィフトバージョン:

func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {

    if string == " " {
        return false
    }

    let userEnteredString = textField.text

    var newString = (userEnteredString! as NSString).stringByReplacingCharactersInRange(range, withString: string) as NSString

    print(newString)

    return true
}


1

ガードを使う

func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
        guard case let textFieldString as NSString = textField.text where
            textFieldString.stringByReplacingCharactersInRange(range, withString: string).length <= maxLength else {
                return false
        }
        return true
    }

0

私の解決策はを使用することUITextFieldTextDidChangeNotificationです。

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

呼び出すことを忘れないでください[[NSNotificationCenter defaultCenter] removeObserver:self];dealloc方法。


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.