要件
指定文字数以上はテキストフィールドに入力させない実装がしたい。
実装
var maxLength: Int = 4
// 適当な所でこのターゲットアクションを設定してください。
@objc func textFieldEditingChanged(textField: UITextField) {
guard let text = textField.text else { return }
textField.text = String(text.prefix(maxLength))
}
UITextFiledDelegateを使わないのは、こちらの記事でヤバそうだと思ったからです。
説明
指定文字数以上はテキストフィールドに入力させない。という要件を、
**「指定文字数以上は切り取る。」**という実装で解決します。
Stringのprefix(_:)
メソッドは先頭から指定した文字数までを切り取って返してくれるメソッドなので、こいつを使います。
しかし prefix(_:)
メソッドの返り値はString
ではなく SubStringなので、直接textFiled.text
への代入はできません。
ドキュメントを読むと、
Stringのイニシャライザに渡してあげれば、SubStringからStringに変換できるよ。
と書いてあるので、その通りにします。
イニシャライザは init(_ substring: Substring)
ですね。
共有状態からスタンドアロンのStringを生成するために初期化を呼んであげるようです。
TIPS
SubStringは高速らしい
今回初めて知ったのですが、 SubString
は元になった String
と保存領域を共有しているらしく高速らしいです。へぇー。
計算量はO(n)らしい
ドキュメントの Discussion
の欄に
Complexity: O(n), where n is the length of substring
と書いてありました。どんな処理をしてるのかは分からないですが、文字数が多ければ多いほど処理が重たくなるって感じですね。