[iOS] UITextFieldやUITextViewで入力できる文字列を制限する
はじめに
こんにちは!加藤 潤です。
今回はUITextField
や UITextView
で入力できる文字列を制限する方法をご紹介します。
開発環境
- Xcode 7.3.1 (7D1014)
- iPhone 6s シミュレータ / iOS 9.3 (13E230)
- Swift 2.2
こんなケースありませんか?
iOSアプリ開発でユーザーに任意のテキストを入力させる場合、UITextField
や UITextView
を使うと思いますが、その際以下のように「入力できる文字列を制限したい」というニーズは多いと思います。
- 半角数字だけ入力させたい
- 半角英数字だけ入力させたい
- メールアドレスで使用可能な文字だけ入力させたい
- etc...
例えば、キーボードタイプをUIKeyboardType.NumberPad
に設定することで半角数字だけ入力させることが可能ですが、キーボードから入力する場合はそれで良いのですが、メモアプリなどからコピー&ペーストで入力できてしまうためこれだけでは実は不十分だったりします。
そこで今回は他のアプリからコピー&ペーストされても指定した条件を満たさないテキストは入力できないように制限したいと思います。
半角数字だけ入力できるようにする
例としてここでは「半角数字だけ入力できるようにする」方法をご紹介します。
まずはそのための正規表現を考えましょう。
こんな感じになると思います。
^[0-9]+$
(0から9が1文字以上)
UITextFieldで入力を制限する
UITextField
で入力を制限するにはUITextFieldDelegate
の下記関数を実装します。
@available(iOS 2.0, *) optional public func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool // return NO to not change text
この関数はUITextField
のテキストに入力がある度に呼ばれます。
引数のtextField
に対象のUITextField、range
に置換される文字列の範囲、string
に置換する文字列が渡ってきます。
このメソッドでtrue
を返せばテキストは変化し、false
を返せばテキストは変化せずに以前のテキストが保持されます。
つまり、このメソッド内でstring
の文字列を正規表現でチェックし、指定したパターンに当てはまる場合だけtrue
を返してあげれば良いということになります。
下記は実装例です。
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool { return string.isEmpty || string.rangeOfString("^[0-9]+$", options: .RegularExpressionSearch, range: nil, locale: nil) != nil }
正規表現チェックには下記関数を使用し、オプションには.RegularExpressionSearch
を指定します。
@warn_unused_result public func rangeOfString(aString: String, options mask: NSStringCompareOptions = default, range searchRange: Range<Index>? = default, locale: NSLocale? = default) -> Range<Index>?
実装のポイントは下記の2点です。
- ユーザーがDeleteキーで文字を削除した場合は
string
が空となるのでstring.isEmpty
を満たす場合もtrueを返すようにする rangeOfString
はマッチしなかった場合はnilが返るので、nilではない場合にtrueを返すようにする
UITextViewで入力を制限する
UITextView
で入力を制限するにはUITextViewDelegate
の下記関数を実装します。
@available(iOS 2.0, *) optional public func textView(textView: UITextView, shouldChangeTextInRange range: NSRange, replacementText text: String) -> Bool
この関数もUITextView
のテキストに入力がある度に呼ばれます。
UITextFieldの時と同じように実装すればOKです。
func textView(textView: UITextView, shouldChangeTextInRange range: NSRange, replacementText text: String) -> Bool { return text.isEmpty || text.rangeOfString("^[0-9]+$", options: .RegularExpressionSearch, range: nil, locale: nil) != nil }
まとめ
今回はUITextField や UITextView で入力できる文字列を制限する方法をご紹介しました。
正規表現の部分を差し替えることで様々な入力要件に対応できるかと思います。