UITextFieldでユーザーが何か入力した時のイベントを取る方法です。
shouldChangeCharactersInRange
方法は2つありまして、1つ目はUITextFieldDelegate
のdelegate
メソッドであるtextField:shouldChangeCharactersInRange:
を使う方法です。
class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() view.backgroundColor = UIColor.lightGrayColor() let tf = UITextField() tf.delegate = self tf.frame = CGRect(x: 10, y: 10, width: 100, height: 40) tf.backgroundColor = UIColor.whiteColor() view.addSubview(tf) } } extension ViewController: UITextFieldDelegate { func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool { // 変更があるとここに来る return true } }
shouldChangeCharactersInRangeはfalseを返すとユーザーの入力を無効化できるので、「文字数が10文字以上だったらユーザーに入力させない」と言った事もできます。
extension ViewController: UITextFieldDelegate { func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool { let text = (textField.text! as NSString).stringByReplacingCharactersInRange(range, withString: string) if text.characters.count > 10 { return false } return true } }
しかしこの方法だと、ユーザーの入力後の文字を取得するのにstringByReplacingCharactersInRange
を使う必要があるのがめんどくさいです。
それと変換中のバックキー押下時のイベントがうまく取れない問題があります。
↓ この状態でバックキーを押すとstringByReplacingCharactersInRange
で正しく文字が取れない。
UIControlEvents.EditingChanged
2つ目の方法はUIControlEvents.EditingChanged
を利用する方法です。
.EditingChanged
なら入力後の文字列を取得できるので、上記の2つの問題を回避できます。
class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() view.backgroundColor = UIColor.lightGrayColor() let tf = UITextField() tf.addTarget(self, action: "textFieldEditingChanged:", forControlEvents: .EditingChanged) tf.frame = CGRect(x: 10, y: 10, width: 100, height: 40) tf.backgroundColor = UIColor.whiteColor() view.addSubview(tf) } } extension ViewController { func textFieldEditingChanged(sender: UITextField) { print(sender.text) // ユーザーの入力完了後の文字が入ってる } }
まとめ
普通に変更イベントを取りたいだけならEditingChanged
、場合によってユーザーの入力をキャンセルしたい場合はshouldChangeCharactersInRange
と使い分けると良さそうです。