最大長UITextField


120

私が試したときどのようにすばやいを使用してUITextFieldに入力できる最大文字数を設定しますか?、10文字全部使ってしまうと消せないことがわかりました。

私ができる唯一のことは、操作をキャンセルすることです(すべての文字を一緒に削除します)。

誰かがキーボードをブロックしない方法を知っていますか?

回答:


294

Swift 5とiOS 12ではtextField(_:shouldChangeCharactersIn:replacementString:)UITextFieldDelegateプロトコルの一部である次のメソッドの実装を試してください。

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    guard let textFieldText = textField.text,
        let rangeOfTextToReplace = Range(range, in: textFieldText) else {
            return false
    }
    let substringToReplace = textFieldText[rangeOfTextToReplace]
    let count = textFieldText.count - substringToReplace.count + string.count
    return count <= 10
}
  • このコードの最も重要な部分は、から変換であるrangeNSRange)はrangeOfTextToReplaceRange<String.Index>)。この変換が重要である理由を理解するには、このビデオチュートリアルを参照してください。
  • このコードを正しく機能させるには、textFieldsmartInsertDeleteType値もに設定する必要がありますUITextSmartInsertDeleteType.no。これにより、貼り付け操作を実行するときに、(不要な)余分なスペースが挿入される可能性がなくなります。

以下の完全なサンプルコードは、に実装textField(_:shouldChangeCharactersIn:replacementString:)する方法を示していますUIViewController

import UIKit

class ViewController: UIViewController, UITextFieldDelegate {

    @IBOutlet var textField: UITextField! // Link this to a UITextField in Storyboard

    override func viewDidLoad() {
        super.viewDidLoad()

        textField.smartInsertDeleteType = UITextSmartInsertDeleteType.no
        textField.delegate = self
    }

    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        guard let textFieldText = textField.text,
            let rangeOfTextToReplace = Range(range, in: textFieldText) else {
                return false
        }
        let substringToReplace = textFieldText[rangeOfTextToReplace]
        let count = textFieldText.count - substringToReplace.count + string.count
        return count <= 10
    }

}

このコードをView Controllerクラスに入れますか?または、接続を確立する必要がありますか?
Isaac Wasserman 2015年

誰かが何らかの条件を設定する必要がある場合..あなたはこのようにすることができます..。if(textField .isEqual(mobileNumberTextfield)){guard let text = textField.text else {return true} let newLength = text.characters.count + string.characters.count-range.length return newLength <= limitLength; } trueを返します。
Narasimha Nallamsetty 2015年

5
Swift 4のtext.characters.count使用は非推奨ですtext.count
Mohamed Salah '10

47

私はそれをこのようにします:

func checkMaxLength(textField: UITextField!, maxLength: Int) {
    if (countElements(textField.text!) > maxLength) {
        textField.deleteBackward()
    }
}

コードは私にとってはうまくいきます。しかし、私は絵コンテで作業します。ストーリーボードで、編集の変更時にビューコントローラーのテキストフィールドにアクションを追加します。


1
countElementsはSwift 2でcountに変更されましたが、変更するとうまくいきます!
ジョン

1
おかげで、countElementsが変更されたため、textField.text?.characters.countを使用できるようになりました。
Anibal R.

1
Tks、それはこの変更でうまく機能しました:Swift 2のcountElements(textField.text!)は次のとおりです:textField.text?.characters.count
kha

32

Swift 4のアップデート

 func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
     guard let text = textField.text else { return true }
     let newLength = text.count + string.count - range.length
     return newLength <= 10
}

15

@Martinの回答から詳細を追加

// linked your button here
@IBAction func mobileTFChanged(sender: AnyObject) {
    checkMaxLength(sender as! UITextField, maxLength: 10)
}

// linked your button here
@IBAction func citizenTFChanged(sender: AnyObject) {
    checkMaxLength(sender as! UITextField, maxLength: 13)
}

func checkMaxLength(textField: UITextField!, maxLength: Int) {
    // swift 1.0
    //if (count(textField.text!) > maxLength) {
    //    textField.deleteBackward()
    //}
    // swift 2.0
    if (textField.text!.characters.count > maxLength) {
        textField.deleteBackward()
    }
}

1
count(textField.text!)はエラーになります。textField.text!.characters.countを使用する必要があります
Regis St-Gelais

1
@ RegisSt-Gelaisに感謝します。それはすでに古い回答です。私は今それを更新しました
Sruit A.Suk

11

Swift 4で

テキストフィールドの10文字の制限と削除を許可(バックスペース)

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        if textField ==  userNameFTF{
            let char = string.cString(using: String.Encoding.utf8)
            let isBackSpace = strcmp(char, "\\b")
            if isBackSpace == -92 {
                return true
            }
            return textField.text!.count <= 9
        }
        return true
    }


8

スウィフト3

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {

            let nsString = NSString(string: textField.text!)
            let newText = nsString.replacingCharacters(in: range, with: string)
            return  newText.characters.count <= limitCount
    }

8

UITextFieldを拡張して、@IBInspectableそれを処理するためのオブジェクトを追加できます。

SWIFT 5

import UIKit
private var __maxLengths = [UITextField: Int]()
extension UITextField {
    @IBInspectable var maxLength: Int {
        get {
            guard let l = __maxLengths[self] else {
                return 150 // (global default-limit. or just, Int.max)
            }
            return l
        }
        set {
            __maxLengths[self] = newValue
            addTarget(self, action: #selector(fix), for: .editingChanged)
        }
    }
    @objc func fix(textField: UITextField) {
        if let t = textField.text {
            textField.text = String(t.prefix(maxLength))
        }
    }
}

その後、属性インスペクターで定義します

ここに画像の説明を入力してください

Swift 4の元の回答を参照してください


2
きれいなコード。しかし、何らかの理由で、絵文字を使用すると、これにより奇妙な編集動作が発生します。編集しようとするたびに、カーソルは行末までスキップします。
Phontaine Judd

5

最後の文字を上書きしたい場合:

let maxLength = 10

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {

    if range.location > maxLength - 1 {
        textField.text?.removeLast()
    }

    return true
}


3

あなたは次のように迅速5またはSWIFT 4で使用することができます 怒鳴るようなイメージの外観 ここに画像の説明を入力してください

  1. ViewControllerにtextFieldを追加します
  2. ViewControllerにテキストに接続する
  3. ビューViewControllerにコードを追加します

     class ViewController: UIViewController , UITextFieldDelegate {
    
      @IBOutlet weak var txtName: UITextField!
    
      var maxLen:Int = 8;
    
     override func viewDidLoad() {
        super.viewDidLoad()
    
        txtName.delegate = self
       }
    
     func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    
         if(textField == txtName){
            let currentText = textField.text! + string
            return currentText.count <= maxLen
         }
    
         return true;
       }
    }

GitHubからフルソースフォームをダウンロードできます: https : //github.com/enamul95/TextFieldMaxLen


1

この投稿で言及されているUITextFieldの元に戻すバグに注意してください:UITextField の最大文字長を設定します

ここであなたはそれを迅速に修正する方法です

if(range.length + range.location > count(textField.text)) {
        return false;
}

絵文字などの使用をサポートする場合:if(range.length + range.location> count(textField.text.utf16)){return false; }
AlexD 2015

1
Here is my version of code. Hope it helps!

    func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
        let invalidCharacters = NSCharacterSet(charactersInString: "0123456789").invertedSet

        if let range = string.rangeOfCharacterFromSet(invalidCharacters, options: nil, range:Range<String.Index>(start: string.startIndex, end: string.endIndex))
        {
            return false
        }

        if (count(textField.text) > 10  && range.length == 0)
        {
            self.view.makeToast(message: "Amount entry is limited to ten digits", duration: 0.5, position: HRToastPositionCenter)
            return false
        }
        else
        {

        }

        return true
    }

1
私はToast UIView拡張機能が好きです:)
Regis St-Gelais 2016

1

私は自分のアプリの1つでこのプロトコル/拡張機能を使用しており、もう少し読みやすくなっています。私はそれがバックスペースをどのように認識し、文字がバックスペースであるかを明示的に伝える方法が好きです。

考慮すべき事項:

1.このプロトコル拡張を実装するものはすべて、文字制限を指定する必要があります。通常、これはViewControllerになりますが、計算されたプロパティとして文字制限を実装し、他の何かを返すことができます。たとえば、モデルの1つの文字制限などです。

2.テキストフィールドのshouldChangeCharactersInRangeデリゲートメソッド内でこのメソッドを呼び出す必要があります。そうしないと、falseを返すなどしてテキスト入力をブロックできなくなります。

3.おそらくバックスペース文字を通過させたいでしょう。そのため、バックスペースを検出するための関数を追加しました。shouldChangeCharactersメソッドはこれをチェックし、早い段階で 'true'を返すことができるため、常にバックスペースを許可できます。

protocol TextEntryCharacterLimited{
    var characterLimit:Int { get } 
}

extension TextEntryCharacterLimited{

    func charactersInTextField(textField:UITextField, willNotExceedCharacterLimitWithReplacementString string:String, range:NSRange) -> Bool{

        let startingLength = textField.text?.characters.count ?? 0
        let lengthToAdd = string.characters.count
        let lengthToReplace = range.length

        let newLength = startingLength + lengthToAdd - lengthToReplace

        return newLength <= characterLimit

    }

    func stringIsBackspaceWith(string:String, inRange range:NSRange) -> Bool{
        if range.length == 1 && string.characters.count == 0 { return true }
        return false
    }

}

興味のある方がいれば、私はGithubリポジトリを持っています。この文字制限動作の一部を取り、iOSフレームワークに入れました。Twitterのような文字制限表示を取得するために実装できるプロトコルがあり、文字制限をどれだけ超えたかが表示されます。

GithubのCharacterLimited Framework


1

デリゲートは1対1の関係であり、他の理由で他の場所で使用したい場合があるため、テキストフィールドの長さを制限して、セットアップ内にこのコードを追加します。

    required init(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)!
        setup()
    }

    required override init(frame: CGRect) {
        super.init(frame: frame)
        setup()
    }

    func setup() {

        // your setup...

        setMaxLength()
    }

    let maxLength = 10

    private func setMaxLength() {
            addTarget(self, action: #selector(textfieldChanged(_:)), for: UIControlEvents.editingChanged)
        }

        @objc private func textfieldChanged(_ textField: UITextField) {
            guard let text = text else { return }
            let trimmed = text.characters.prefix(maxLength)
            self.text = String(trimmed)

        }

0

私はこれを使用しています。

制限3文字

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {

        if let txt = textField.text {
            let currentText = txt + string
            if currentText.count > 3 {
                return false
            }
            return true
        }
        return true
    }

0

スウィフト5

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        let MAX_LENGTH = 4
        let updatedString = (textField.text! as NSString).replacingCharacters(in: range, with: string)
        return updatedString.count <= MAX_LENGTH
    }

-3

既存の文字列と入力の合計が10より大きいかどうかを確認する必要があります。

   func textField(textField: UITextField!,shouldChangeCharactersInRange range: NSRange,    replacementString string: String!) -> Bool {
      NSUInteger newLength = textField.text.length + string.length - range.length;
      return !(newLength > 10)
   }

5
あなたのコードは間違っています。1.(NSUIntegerではなく)Swiftでletまたはvarを使用して定数または変数を宣言する必要があります。2. textField.textとstringはString型です。長さはSwiftのStringのプロパティ/メソッドではありません。
Imanou Petit 2014
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.