Maksimum uzunluk UITextField


120

Denediğimde swift kullanarak bir UITextField'a girilebilecek maksimum karakter sayısını nasıl ayarlarsınız? , 10 karakterin hepsini kullanırsam, karakteri de silemeyeceğimi gördüm.

Yapabileceğim tek şey işlemi iptal etmek (tüm karakterleri birlikte silmek).

Klavyeyi nasıl engellemeyeceğini bilen var mı (böylece diğer harfleri / sembolleri / sayıları ekleyemem, ancak geri tuşunu kullanabilirim)?

Yanıtlar:


295

Swift 5 ve iOS 12 ile, protokolün textField(_:shouldChangeCharactersIn:replacementString:)parçası olan aşağıdaki yöntem uygulamasını deneyin 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
}
  • Bu kodun en önemli kısmı ile ilgili dönüşüm range( NSRangekadar) rangeOfTextToReplace( Range<String.Index>). Bu dönüşümün neden önemli olduğunu anlamak için bu eğitim videosuna bakın .
  • Bu kodun düzgün çalışmasını sağlamak için textField's smartInsertDeleteTypedeğerini de olarak ayarlamalısınız UITextSmartInsertDeleteType.no. Bu, bir yapıştırma işlemi gerçekleştirirken (istenmeyen) fazladan boşluk eklenmesini önleyecektir.

Nasıl uygulamaya gösterileri altında komple örnek kod textField(_:shouldChangeCharactersIn:replacementString:)bir de 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
    }

}

Bu kodu sadece görünüm denetleyicisi sınıfınıza mı koyuyorsunuz? Yoksa bağlantı kurmam mı gerekiyor?
Isaac Wasserman

Birinin şart koyması gerekiyorsa .. bunu yapabilirsin ... 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 döndürür;
Narasimha Nallamsetty

6
Swift 4 text.characters.countiçin kullanımdan kaldırıldıtext.count
Mohamed Salah

47

Bunu böyle yapıyorum:

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

Kod benim için çalışıyor. Ama film şeridi ile çalışıyorum. Storyboard'da, değiştirilen düzenleme üzerine görünüm denetleyicisindeki metin alanı için bir eylem ekliyorum .


1
countElements, Swift 2'de sayılacak şekilde değiştirildi, ancak bu benim için işe yarıyor!
John

1
Teşekkürler, countElements değiştirildiğinden beri textField.text? .Characters.count kullanabilirsiniz.
Anibal R.

1
Tks, bu değişiklikle harika çalıştı: Swift 2'deki countElements (textField.text!): TextField.text? .Characters.count
kha

33

Swift 4 Güncellemesi

 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 yanıtından daha fazla ayrıntı ekleyin

// 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!) hata veriyor. TextField.text! .Characters.count
Regis St-Gelais

1
RegisSt-Gelais @ sayesinde Zaten eski bir cevap, şimdi güncellenen
Sruit A.Suk

11

Swift 4'te

Metin alanı için 10 karakter sınırlaması ve silmeye izin verme (geri alma)

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
func checkMaxLength(textField: UITextField!, maxLength: Int) {
        if (textField.text!.characters.count > maxLength) {
            textField.deleteBackward()
        }
}

IOS 9 için küçük bir değişiklik


8

Hızlı 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'ı genişletebilir ve @IBInspectableişlemek için bir nesne ekleyebilirsiniz :

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))
        }
    }
}

ve bundan sonra bunu nitelik denetçisinde tanımlayın

görüntü açıklamasını buraya girin

Swift 4 orijinal cevabına bakın


2
Güzel, temiz kod. Ancak bazı nedenlerden dolayı bu, emojiyi kullandığınızda garip düzenleme davranışına neden olur. Her düzenlemeye çalıştığınızda imleç satırın sonuna atlar.
Phontaine Judd

5

Son harfin üzerine yazmak istiyorsanız:

let maxLength = 10

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

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

    return true
}

4

Kullanarak bir çözüm yayınladım IBInspectable, böylece hem arayüz oluşturucuda hem de programlı olarak maksimum uzunluk değerini değiştirebilirsiniz. Buradan kontrol edin


3

Swift 5 veya swift 4 gibi görüntüyü feryat gibi kullanabilirsiniz görüntü açıklamasını buraya girin

  1. View Controller'da textField ekle
  2. ViewController'a metne bağlanın
  3. kodu ViewController görünümüne ekleyin

     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;
       }
    }

Tam Kaynak formunu GitHub'dan indirebilirsiniz: https://github.com/enamul95/TextFieldMaxLen


1

Bu gönderide bahsedilen UITextField için geri alma hatasına dikkat edin: Bir UITextField'ın maksimum karakter uzunluğunu ayarlayın

işte bunu hızlıca nasıl düzeltirsin

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

Emoji ve benzeri kullanımı desteklemek istiyorsanız: if (range.length + range.location> count (textField.text.utf16)) {return false; }
AlexD

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 uzantısını beğendim :)
Regis St-Gelais

1

Bu protokolü / uzantıyı uygulamalarımdan birinde kullanıyorum ve biraz daha okunaklı. Geri boşlukları nasıl tanıdığını ve bir karakterin ne zaman geri alacağını size açıkça söylemesini seviyorum.

Dikkate alınması gereken bazı şeyler:

1. Bu protokol uzantısını uygulayan ne olursa olsun, bir karakter sınırı belirtmelidir. Bu tipik olarak ViewController'ınız olacaktır, ancak karakter sınırını hesaplanmış bir özellik olarak uygulayabilir ve başka bir şey, örneğin modellerinizden birinde bir karakter sınırı döndürebilirsiniz.

2. Bu yöntemi metin alanınızın shouldChangeCharactersInRange temsilci yönteminin içinde çağırmanız gerekecektir. Aksi takdirde, yanlış vb. Döndürerek metin girişini engelleyemezsiniz.

3. Büyük olasılıkla geri alma karakterlerinin geçmesine izin vermek isteyeceksiniz. Bu yüzden geri boşlukları tespit etmek için ekstra fonksiyon ekledim. ShouldChangeCharacters yönteminiz bunu kontrol edebilir ve erkenden 'true' döndürebilir, böylece her zaman geri boşluklara izin verebilirsiniz.

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
    }

}

Herhangi biriniz ilgilenirse, bu karakter sınırı davranışının bir kısmını aldığım ve bir iOS çerçevesine koyduğum bir Github depom var. Karakter sınırını ne kadar aştığınızı gösteren Twitter benzeri bir karakter sınırı ekranı elde etmek için uygulayabileceğiniz bir protokol var.

Github'da CharacterLimited Framework


1

Temsilciler 1'e 1 ilişki olduğundan ve başka nedenlerle başka bir yerde kullanmak isteyebileceğim için, bu kodu kurulumlarına ekleyerek metin alanı uzunluğunu kısıtlamayı seviyorum:

    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

Bunu kullanıyorum;

3 karakterle sınırlıdır

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

Swift 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

Mevcut dizge artı girdinin 10'dan büyük olup olmadığını kontrol etmeniz gerekir.

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

5
Kodunuz yanlış. 1. Swift'de let veya var ile sabitinizi veya değişkeninizi bildirmelisiniz (NSUInteger değil). 2. textField.text ve string, String türündedir. Uzunluk, Swift'de String'in bir özelliği / yöntemi değildir.
Imanou Petit
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.