UITextField
をロードするときに、iPhone SDK での最大文字数を設定するにはどうすればよいですかUIView
?
ベストアンサー1
クラスには最大長プロパティはありませんがUITextField
、テキスト フィールドを設定しdelegate
、次のデリゲート メソッドを実装することで、この機能を実現するのは比較的簡単です。
オブジェクティブ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
。置換は、空でない文字列による範囲削除のみです。
クラッシュする「元に戻す」バグに関するメモ
コメントに記載されているように、UITextField
クラッシュにつながる可能性のあるバグがあります。
フィールドに貼り付けても、検証実装によって貼り付けが阻止された場合、貼り付け操作はアプリケーションの元に戻すバッファーに記録されます。その後、元に戻す操作を実行すると (デバイスを振って元に戻す操作を確認する)、貼り付けたと思われる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
}
お役に立てれば幸いです。