1. ホーム
  2. ios

[解決済み] UITextFieldの最大文字数を設定します。

2022-03-20 17:42:23

質問

の最大文字数を設定するにはどうすればよいですか? UITextField を読み込むと、iPhone SDK上で UIView ?

解決方法は?

一方 UITextField クラスには最大長のプロパティがありませんが、この機能を得るのは比較的簡単で、テキストフィールドの delegate を作成し、以下のデリゲートメソッドを実装します。

Objective-C

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
    // Prevent crashing undo bug – see note below.
    if(range.length + range.location > textField.text.length)
    {
        return NO;
    }
        
    NSUInteger newLength = [textField.text length] + [string length] - range.length;
    return newLength <= 25;
}

スウィフト

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    
    let currentCharacterCount = textField.text?.count ?? 0
    if range.length + range.location > currentCharacterCount {
        return false
    }
    let newLength = currentCharacterCount + string.count - range.length
    return newLength <= 25
}

テキスト・フィールドが変更される前に、UITextField はデリゲートに、指定されたテキスト が必要です。 が変更されます。この時点ではテキストフィールドは変更されていないので、現在の長さと、挿入する文字列(コピーしたテキストを貼り付けるか、キーボードで1文字入力する)の長さから、範囲の長さを引いたものを取得します。この値が長すぎる場合(この例では25文字以上)、次のように返します。 NO で変更を禁止しています。

テキストフィールドの末尾に1文字だけ入力する場合は range.location は現在のフィールドの長さになり range.length は0になります。なぜなら、何も置き換えたり消したりしていないからです。テキストフィールドの途中に挿入する場合は、単に別の range.location を意味し、複数の文字を貼り付けることは、単に string は複数の文字が含まれています。

一文字の削除や複数文字のカットは、指定した range を0以外の長さで、かつ空文字列で指定します。置換は、空でない文字列による単なる範囲削除です。

undo"クラッシュするバグについてのメモ

コメントにもありますが UITextField が発生し、クラッシュする可能性があります。

フィールドに貼り付けても、バリデーション実装によって貼り付けが阻止された場合、貼り付け操作はアプリケーションのアンドゥバッファに記録されたままです。その後、(デバイスをシェイクしてUndoを確認することで)Undoを実行すると UITextField は、その文字列を置き換えようとします。 が考える を空文字列で貼り付けました。これはクラッシュします。 実際に を自分自身に貼り付けます。存在しない文字列の一部を置き換えようとします。

幸いなことに UITextField このような自滅を防ぐためです。ただ、置換しようとする範囲が する は、現在の文字列の中に存在します。これは、上記の最初のサニティチェックが行うことです。

swift 3.0 でコピー&ペーストが正常に動作しています。

func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
        let str = (textView.text + text)
        if str.characters.count <= 10 {
            return true
        }
        textView.text = str.substring(to: str.index(str.startIndex, offsetBy: 10))
        return false
    }

お役に立てれば幸いです。