Imposta la lunghezza massima dei caratteri di un UITextField


Risposte:


1029

Sebbene la UITextFieldclasse non abbia proprietà di lunghezza massima, è relativamente semplice ottenere questa funzionalità impostando i campi di testo delegatee implementando il seguente metodo delegato:

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

veloce

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
}

Prima che il campo di testo cambi, UITextField chiede al delegato se il testo specificato deve essere modificato. Il campo di testo non è cambiato a questo punto, quindi prendiamo la lunghezza corrente e la lunghezza della stringa che stiamo inserendo (incollando il testo copiato o digitando un singolo carattere usando la tastiera), meno la lunghezza dell'intervallo. Se questo valore è troppo lungo (più di 25 caratteri in questo esempio), restituireNO a vietare la modifica.

Quando si digita un singolo carattere alla fine di un campo di testo, range.locationsarà la lunghezza del campo corrente e range.lengthsarà 0 perché non stiamo sostituendo / eliminando nulla. Inserire nel mezzo di un campo di testo significa solo un diverso range.location, e incollare più caratteri significa solo che stringcontiene più di un carattere.

L'eliminazione di singoli caratteri o il taglio di più caratteri è specificato da a rangecon una lunghezza diversa da zero e una stringa vuota. La sostituzione è solo una cancellazione dell'intervallo con una stringa non vuota.

Una nota sul bug "annulla" in crash

Come menzionato nei commenti, esiste un bug UITextFieldche può causare un arresto anomalo.

Se si incolla nel campo, ma la copia viene impedita dall'implementazione della convalida, l'operazione incolla viene comunque registrata nel buffer di annullamento dell'applicazione. Se quindi esegui un annullamento (scuotendo il dispositivo e confermando un Annulla), il UITextFieldtentativo di sostituire la stringa che ritiene incollata su una stringa vuota. Ciò andrà in crash perché non è mai in realtà incollato la stringa a se stesso. Tenterà di sostituire una parte della stringa che non esiste.

Fortunatamente puoi proteggerti UITextFielddall'uccidersi in questo modo. Hai solo bisogno di assicurarsi che la gamma si propone di sostituire lo fa esistere nel suo stringa corrente. Questo è ciò che fa il controllo di integrità iniziale sopra.

veloce 3.0 con copia e incolla che funzionano bene.

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
    }

Spero ti sia utile.


7
Ho trovato una soluzione circondando quelle 2 righe con if (textField == _ssn) {} e aggiungendo return YES; alla fine del metodo, che consentirà a tutti gli altri UITextField di accettare il testo senza alcuna restrizione. Nifty!
Kyle Clegg,

55
Buona risposta, ma l'operatore ternario è superfluo; potresti semplicemente metterereturn newLength <= 25;
jowie il

2
Che cosa succede se si desidera solo che il testo non si riversi sulla cornice del campo di testo; non tutti i caratteri hanno la stessa larghezza, giusto?
Morkrom,

2
C'è davvero un bug di annullamento come menziona @bcherry - testato UITextFieldsu iPad iOS 8.1. (+1 per commentare). L'autore aggiungerebbe qualcosa al riguardo in quanto è la risposta più votata? Sono felice di fare una modifica, ma la mia sembra regolarmente essere respinta! :-)
Benjohn,

8
@bherry In Swift, il controllo per il caso di annullamento sembra interrompere l'ingresso di emoji. Il conteggio (textField.text) non dovrebbe essere effettivamente count (textField.text.utf16) per corrispondere al rapporto objc / uikit nell'intervallo (rispetto alla variante di conteggio di Swift sulle stringhe)?
rcw3,

62

Swift 4

import UIKit

private var kAssociationKeyMaxLength: Int = 0

extension UITextField {

    @IBInspectable var maxLength: Int {
        get {
            if let length = objc_getAssociatedObject(self, &kAssociationKeyMaxLength) as? Int {
                return length
            } else {
                return Int.max
            }
        }
        set {
            objc_setAssociatedObject(self, &kAssociationKeyMaxLength, newValue, .OBJC_ASSOCIATION_RETAIN)
            addTarget(self, action: #selector(checkMaxLength), for: .editingChanged)
        }
    }

    @objc func checkMaxLength(textField: UITextField) {
        guard let prospectiveText = self.text,
            prospectiveText.count > maxLength
            else {
                return
        }

        let selection = selectedTextRange

        let indexEndOfText = prospectiveText.index(prospectiveText.startIndex, offsetBy: maxLength)
        let substring = prospectiveText[..<indexEndOfText]
        text = String(substring)

        selectedTextRange = selection
    }
}

Modifica: risolto problema di perdita di memoria.

inserisci qui la descrizione dell'immagine


Ottima idea Frouo! L'ho ampliato nella mia risposta per spostare il taglio maxLength su un'estensione String in modo che possa essere utilizzato anche per cose come istanze UITextView e per aggiungere una funzione di convenienza per sfruttare queste estensioni String in un'estensione UITextField.
Scott Gardner,

1
Questa variabile globale non crea perdite di memoria, mantenendo i riferimenti a tutte le visualizzazioni di testo (che fanno riferimento alle panoramiche fino alla radice-)
Ixx

3
@Ixx Ho modificato per risolvere il problema di perdita di memoria che hai sottolineato + swift 3. Grazie
frouo

1
il modo più bello per raggiungerlo! Grazie
Victor Choy,

qualcuno può fornirmi la sua versione obiettiva
MRizwan33

56

Grazie agosto! ( Posta )

Questo è il codice con cui ho finito che funziona:

#define MAX_LENGTH 20

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
    if (textField.text.length >= MAX_LENGTH && range.length == 0)
    {
        return NO; // return NO to not change text
    }
    else
    {return YES;}
}

19
Sfortunatamente, questa soluzione non riesce a bloccare il copia e incolla degli utenti in un campo di testo, consentendo loro di bypassare il limite. La risposta di Sickpea affronta correttamente questa situazione.
Formica,

5
Che cosa hanno le persone che hanno una dichiarazione if per restituire NO o SÌ? Prova questo: return! (TextField.text.length> = MAX_LENGTH && range.length == 0);
Matt Parkins,

o questoreturn textField.text.length < MAX_LENGTH || range.length != 0;
igrek,

22

Per completare la risposta di agosto , una possibile implementazione della funzione proposta (vedere il delegato di UITextField ).

Non ho testato il codice domness , ma il mio non si blocca se l'utente ha raggiunto il limite ed è compatibile con una nuova stringa che viene sostituita con una più piccola o uguale.

-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
    //limit the size :
    int limit = 20;
    return !([textField.text length]>limit && [string length] > range.length);
}

17

Non puoi farlo direttamente - UITextFieldnon ha attributo maxLength , ma puoi impostare il UITextField'sdelegato, quindi utilizzare:

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string

5
Sono d'accordo, questo è il modo migliore per andare avanti, ma rimane un po 'un trucco. Invia una segnalazione di bug ad Apple per visualizzare una proprietà per la lunghezza del testo. Sono decisamente interessato anche a questo.
avvocato

5
@avocade, non è un trucco: è un esempio in cui devi fare un codice di base che Apple avrebbe dovuto fare per te. Ci sono molti esempi di questo nell'SDK di iOS.
Dan Rosenstark,

13

Spesso hai più campi di input con una lunghezza diversa.

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
    int allowedLength;
    switch(textField.tag) {
        case 1: 
            allowedLength = MAXLENGTHNAME;      // triggered for input fields with tag = 1
            break;
        case 2:
            allowedLength = MAXLENGTHADDRESS;   // triggered for input fields with tag = 2
            break;
        default:
            allowedLength = MAXLENGTHDEFAULT;   // length default when no tag (=0) value =255
            break;
    }

    if (textField.text.length >= allowedLength && range.length == 0) {
        return NO; // Change not allowed
    } else {
        return YES; // Change allowed
    }
}

12

Il modo migliore sarebbe quello di impostare una notifica sulla modifica del testo. Nel tuo -awakeFromNibmetodo del controller di visualizzazione ti consigliamo:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(limitTextField:) name:@"UITextFieldTextDidChangeNotification" object:myTextField];

Quindi nella stessa classe aggiungi:

- (void)limitTextField:(NSNotification *)note {
    int limit = 20;
    if ([[myTextField stringValue] length] > limit) {
        [myTextField setStringValue:[[myTextField stringValue] substringToIndex:limit]];
    }
}

Quindi collega l'outlet myTextFieldal tuo UITextFielde non ti permetterà di aggiungere altri personaggi dopo aver raggiunto il limite. Assicurati di aggiungere questo al tuo metodo dealloc:

[[NSNotificationCenter defaultCenter] removeObserver:self name:@"UITextFieldTextDidChangeNotification" object:myTextField];

Anche se l'ho fatto per rimuovere errori> myTextField.text = [myTextField.text substringToIndex: limit];
Luca,

11

Ho creato questa sottoclasse UITextFieldLimit:

  • Sono supportati più campi di testo
  • Imposta il limite di lunghezza del testo
  • Prevenzione della pasta
  • Visualizza un'etichetta di caratteri a sinistra all'interno del campo di testo, che viene nascosta quando si interrompe la modifica.
  • Scuoti l'animazione quando non sono rimasti personaggi.

Prendi il UITextFieldLimit.he UITextFieldLimit.mda questo repository GitHub:

https://github.com/JonathanGurebo/UITextFieldLimit

e inizia a provare!

Contrassegna il tuo UITextField creato dallo storyboard e collegalo alla mia sottoclasse usando Identity Inspector:

Ispettore identità

Quindi è possibile collegarlo a un IBOutlet e impostare il limite (il valore predefinito è 10).


Il file ViewController.h dovrebbe contenere: (se non si desidera modificare l'impostazione, come il limite)

#import "UITextFieldLimit.h"

/.../

@property (weak, nonatomic) IBOutlet UITextFieldLimit *textFieldLimit; // <--Your IBOutlet

Il tuo file ViewController.m dovrebbe @synthesize textFieldLimit.


Imposta il limite di lunghezza del testo nel tuo file ViewController.m:

- (void)viewDidLoad
{
    [super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.

    [textFieldLimit setLimit:25];// <-- and you won't be able to put more than 25 characters in the TextField.
}

Spero che la lezione ti aiuti. In bocca al lupo!


Per il piccolo bisogno del limite del personaggio, penso che aggiungere la tua classe sarebbe eccessivo.
Domness,

Ancora sforzo apprezzato.
Mietitore

11

Questo dovrebbe essere sufficiente per risolvere il problema (sostituire 4 con il limite desiderato). Assicurati di aggiungere un delegato in IB.

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
     NSString *newString = [textField.text stringByReplacingCharactersInRange:range withString:string];
     return (newString.length<=4);
}

9

Usa l'estensione sotto per impostare la lunghezza massima del carattere di a UITextFielde UITextView.

Swift 4.0

    private var kAssociationKeyMaxLength: Int = 0
    private var kAssociationKeyMaxLengthTextView: Int = 0
    extension UITextField {


        @IBInspectable var maxLength: Int {
            get {
                if let length = objc_getAssociatedObject(self, &kAssociationKeyMaxLength) as? Int {
                    return length
                } else {
                    return Int.max
                }
            }
            set {
                objc_setAssociatedObject(self, &kAssociationKeyMaxLength, newValue, .OBJC_ASSOCIATION_RETAIN)
                addTarget(self, action: #selector(checkMaxLength), for: .editingChanged)
            }
        }

        @objc func checkMaxLength(textField: UITextField) {
            guard let prospectiveText = self.text,
                prospectiveText.count > maxLength
                else {
                    return
            }

            let selection = selectedTextRange

            let indexEndOfText = prospectiveText.index(prospectiveText.startIndex, offsetBy: maxLength)
            let substring = prospectiveText[..<indexEndOfText]
            text = String(substring)

            selectedTextRange = selection
        }
    }

UITextView

extension UITextView:UITextViewDelegate {


        @IBInspectable var maxLength: Int {
            get {
                if let length = objc_getAssociatedObject(self, &kAssociationKeyMaxLengthTextView) as? Int {
                    return length
                } else {
                    return Int.max
                }
            }
            set {
                self.delegate = self

                objc_setAssociatedObject(self, &kAssociationKeyMaxLengthTextView, newValue, .OBJC_ASSOCIATION_RETAIN)
            }
        }

        public func textViewDidChange(_ textView: UITextView) {
            checkMaxLength(textField: self)
        }
        @objc func checkMaxLength(textField: UITextView) {
            guard let prospectiveText = self.text,
                prospectiveText.count > maxLength
                else {
                    return
            }

            let selection = selectedTextRange

            let indexEndOfText = prospectiveText.index(prospectiveText.startIndex, offsetBy: maxLength)
            let substring = prospectiveText[..<indexEndOfText]
            text = String(substring)

            selectedTextRange = selection
        }
    }

È possibile impostare il limite di seguito.

inserisci qui la descrizione dell'immagine


la migliore risposta di gran lunga ,, grazie mille ottima soluzione quando ci sono molti campi di testo che richiedono lunghezze diverse
Carlos Norena,

Davvero un'ottima soluzione per il limite di input dei caratteri di controllo textfield e textview. Risparmia anche righe di codice e tempo per gli sviluppatori ... :)
Sandip Patel - SM

Funziona meglio delle altre soluzioni che ho trovato. Ad esempio, se hai emoji nel tuo campo di testo, altre estensioni che ho trovato potrebbero saltare alla fine della riga durante la modifica. Ma il tuo codice non lo fa. Grazie!
Phontaine Judd il

7

Simulo l'effettiva sostituzione della stringa che sta per accadere per calcolare la lunghezza della stringa futura:

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {

    NSString *newString = [textField.text stringByReplacingCharactersInRange:range withString:string];

    if([newString length] > maxLength)
       return NO;

    return YES;
}

7

Swift 3 versione // ***** NON funziona con Swift 2.x! ***** //

Innanzitutto crea un nuovo file Swift: TextFieldMaxLength.swift, quindi aggiungi il codice seguente:

import UIKit

private var maxLengths = [UITextField: Int]()

extension UITextField {

   @IBInspectable var maxLength: Int {

      get {

          guard let length = maxLengths[self] 
             else {
                return Int.max
      }
      return length
   }
   set {
      maxLengths[self] = newValue
      addTarget(
         self,
         action: #selector(limitLength),
         for: UIControlEvents.editingChanged
      )
   }
}
func limitLength(textField: UITextField) {
    guard let prospectiveText = textField.text,
        prospectiveText.characters.count > maxLength
    else {
        return
    }

   let selection = selectedTextRange
   let maxCharIndex = prospectiveText.index(prospectiveText.startIndex, offsetBy: maxLength)
   text = prospectiveText.substring(to: maxCharIndex)
   selectedTextRange = selection
   }
}

e poi vedrai nello Storyboard un nuovo campo (Lunghezza massima) quando selezioni un campo di testo

se hai ancora domande controlla questo link: http://www.globalnerdy.com/2016/05/18/ios-programming-trick-how-to-use-xcode-to-set-a-text-fields -Massima-lunghezza-studio-stile visivo /


Attenzione, questa variabile globale crea perdite di memoria, mantenendo i riferimenti a tutte le visualizzazioni di testo.
dal

6

Usando Interface builder puoi collegare e ottenere l'evento per "Modifica modificata" in una qualsiasi delle tue funzioni. Ora puoi inserire la lunghezza

- (IBAction)onValueChange:(id)sender 
{
    NSString *text = nil;
    int MAX_LENGTH = 20;
    switch ([sender tag] ) 
    {
        case 1: 
        {
            text = myEditField.text;
            if (MAX_LENGTH < [text length]) {
                myEditField.text = [text substringToIndex:MAX_LENGTH];
            }
        }
            break;
        default:
            break;
    }

}

6

Il codice seguente è simile alla risposta di sickp ma gestisce correttamente le operazioni di copia e incolla. Se si tenta di incollare un testo più lungo del limite, il codice seguente troncherà il testo per adattarlo al limite invece di rifiutare completamente l'operazione di incollaggio.

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
    static const NSUInteger limit = 70; // we limit to 70 characters
    NSUInteger allowedLength = limit - [textField.text length] + range.length;
    if (string.length > allowedLength) {
        if (string.length > 1) {
            // get at least the part of the new string that fits
            NSString *limitedString = [string substringToIndex:allowedLength];
            NSMutableString *newString = [textField.text mutableCopy];
            [newString replaceCharactersInRange:range withString:limitedString];
            textField.text = newString;
        }
        return NO;
    } else {
        return YES;
    }
}

6

Esiste una soluzione generica per impostare la lunghezza massima in Swift. Con IBInspectable puoi aggiungere un nuovo attributo in Xcode Attribute Inspector.inserisci qui la descrizione dell'immagine

import UIKit
private var maxLengths = [UITextField: Int]()
extension UITextField {

    @IBInspectable var maxLength: Int {
        get {
            guard let length = maxLengths[self]
            else {
                return Int.max
            }
            return length
        }
        set {
            maxLengths[self] = newValue
            addTarget(
                self,
                action: Selector("limitLength:"),
                forControlEvents: UIControlEvents.EditingChanged
            )
        }
    }

    func limitLength(textField: UITextField) {
        guard let prospectiveText = textField.text
            where prospectiveText.characters.count > maxLength else {
                return
        }
        let selection = selectedTextRange
        text = prospectiveText.substringWithRange(
            Range<String.Index>(prospectiveText.startIndex ..< prospectiveText.startIndex.advancedBy(maxLength))
        )
        selectedTextRange = selection
    }

}

Soluzione pulita e perfetta
Eduardo,

Tenere un UITextField in un campo globale li manterrà in memoria anche dopo che UIViewController è stato eliminato. Questa è una perdita di memoria. Non usare questo metodo
Gunhan,

5

Per farlo funzionare con taglia e incolla di stringhe di qualsiasi lunghezza, suggerirei di cambiare la funzione in qualcosa del tipo:

#define MAX_LENGTH 20

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
    {
        NSInteger insertDelta = string.length - range.length;

        if (textField.text.length + insertDelta > MAX_LENGTH)
        {
           return NO; // the new string would be longer than MAX_LENGTH
        }
        else {
            return YES;
        }
    }

4

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
}

Perché il guard?
oddRaven,

controlla se il testo è nullo, se vuoi, puoi anche usare se @oddRaven
Shan Ye

3

Swift 2.0 +

Prima di tutto crea una classe per questo processo. Chiamiamolo StringValidator.swift.

Quindi basta incollare il seguente codice al suo interno.

import Foundation

extension String {

func containsCharactersIn(matchCharacters: String) -> Bool {
let characterSet = NSCharacterSet(charactersInString: matchCharacters)
return self.rangeOfCharacterFromSet(characterSet) != nil
}

func containsOnlyCharactersIn(matchCharacters: String) -> Bool {
let disallowedCharacterSet = NSCharacterSet(charactersInString: matchCharacters).invertedSet
return self.rangeOfCharacterFromSet(disallowedCharacterSet) == nil
}


func doesNotContainCharactersIn(matchCharacters: String) -> Bool {
let characterSet = NSCharacterSet(charactersInString: matchCharacters)
return self.rangeOfCharacterFromSet(characterSet) == nil
}

func isNumeric() -> Bool
{
let scanner = NSScanner(string: self)
scanner.locale = NSLocale.currentLocale()

return scanner.scanDecimal(nil) && scanner.atEnd
}

}

Ora salva la lezione .....

Utilizzo ..

Ora vai alla tua classe viewController.swift e crea le prese del tuo campo di testo come ..

@IBOutlet weak var contactEntryTxtFld: UITextField! //First textfield
@IBOutlet weak var contactEntryTxtFld2: UITextField!   //Second textfield

Ora vai al metodo shouldChangeCharactersInRange del campo di testo e usa come il seguente.

func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
    if string.characters.count == 0 {
        return true
    }
    let latestText = textField.text ?? ""
    let checkAbleText = (latestText as NSString).stringByReplacingCharactersInRange(range, withString: string)


    switch textField {

    case contactEntryTxtFld:
        return checkAbleText.containsOnlyCharactersIn("0123456789") && prospectiveText.characters.count <= 5

    case contactEntryTxtFld2:
        return checkAbleText.containsOnlyCharactersIn("0123456789") && prospectiveText.characters.count <= 5

    default:
        return true
    }

}

Non dimenticare di impostare il protocollo / i metodi delegati dei campi di testo.

Lasciami spiegare questo ... Sto usando il semplice processo di estensione della stringa che ho scritto all'interno di un'altra classe. Ora sto solo chiamando quei metodi di estensione da un'altra classe dove ne ho bisogno aggiungendo check e valore massimo.

Caratteristiche...

  1. Imposta il limite massimo di un determinato campo di testo.
  2. Imposta il tipo di chiavi accettate per un particolare campo di testo.

I ...

contieneSoloCaratteriIn // Accetta solo caratteri.

contieneCaratteriIn // Accetta la combinazione di caratteri

doesNotContainsCharactersIn // Non accetta caratteri

Spero che questo abbia aiutato ... Grazie ..


3

veloce 3.0

Questo codice funziona bene quando si incolla la stringa più dei limiti di carattere.

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
    }

Grazie per i tuoi voti :)


2
UITextField, non UITextView.
Jonny

3

Fornisco una risposta supplementare basata su @Frouo. Penso che la sua risposta sia il modo più bello. Perché è un controllo comune che possiamo riutilizzare.

private var kAssociationKeyMaxLength: Int = 0

extension UITextField {

    @IBInspectable var maxLength: Int {
        get {
            if let length = objc_getAssociatedObject(self, &kAssociationKeyMaxLength) as? Int {
                return length
            } else {
                return Int.max
            }
        }
        set {
            objc_setAssociatedObject(self, &kAssociationKeyMaxLength, newValue, .OBJC_ASSOCIATION_RETAIN)
            self.addTarget(self, action: #selector(checkMaxLength), for: .editingChanged)
        }
    }

    func checkMaxLength(textField: UITextField) {

        guard !self.isInputMethod(), let prospectiveText = self.text,
            prospectiveText.count > maxLength
            else {
                return
        }

        let selection = selectedTextRange
        let maxCharIndex = prospectiveText.index(prospectiveText.startIndex, offsetBy: maxLength)
        text = prospectiveText.substring(to: maxCharIndex)
        selectedTextRange = selection
    }

    //The method is used to cancel the check when use Chinese Pinyin input method.
    //Becuase the alphabet also appears in the textfield when inputting, we should cancel the check.
    func isInputMethod() -> Bool {
        if let positionRange = self.markedTextRange {
            if let _ = self.position(from: positionRange.start, offset: 0) {
                return true
            }
        }
        return false
    }

}

2

Questo è il modo corretto di gestire la lunghezza massima su UITextField, consente alla chiave di ritorno di uscire dalle dimissioni del campo di testo come primo risponditore e consente all'utente di tornare indietro quando raggiungono il limite

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
int MAX_LENGHT = 5;
    if([string isEqualToString:@"\n"])
    {
        [textField resignFirstResponder];
        return FALSE;
    }
    else if(textField.text.length > MAX_LENGHT-1)
    {
        if([string isEqualToString:@""] && range.length == 1)
        {
            return TRUE;
        }
        else
        {
            return FALSE;
        }
    }
    else
    {
        return TRUE;
    }
}

2

Che dire di questo semplice approccio. Funziona bene per me.

extension UITextField {

    func  charactersLimit(to:Int) {

        if (self.text!.count > to) {
            self.deleteBackward()
        }
    }
}

Poi:

someTextField.charactersLimit(to:16)

1

Altre risposte non gestiscono il caso in cui l'utente può incollare una lunga stringa dagli appunti. Se incollo una stringa lunga, dovrebbe essere troncata ma mostrata. Usa questo nel tuo delegato:

static const NSUInteger maxNoOfCharacters = 5;

-(IBAction)textdidChange:(UITextField * )textField
{
NSString * text = textField.text;

if(text.length > maxNoOfCharacters)
{
    text = [text substringWithRange:NSMakeRange(0, maxNoOfCharacters)];
    textField.text = text;
}

// use 'text'

}

1

Sono arrivato a 1 riga di codice :)

Imposta il delegato della vista di testo su "self", quindi aggiungi il <UITextViewDelegate>tuo .h e il seguente codice nel tuo .m .... puoi regolare il numero "7" in modo che sia il tuo numero MASSIMO di caratteri.

-(BOOL)textView:(UITextView *)a shouldChangeTextInRange:(NSRange)b replacementText:(NSString *)c {
    return ((a.text.length+c.length<=7)+(c.length<1)+(b.length>=c.length)>0);
}

Questo codice spiega la digitazione di nuovi caratteri, l'eliminazione di caratteri, la selezione di caratteri, quindi la digitazione o l'eliminazione, la selezione di caratteri e il taglio, l'incollaggio in generale e la selezione di caratteri e incolla.

Fatto!






In alternativa, sarebbe un altro modo interessante per scrivere questo codice con operazioni a bit

-(BOOL)textView:(UITextView *)a shouldChangeTextInRange:(NSRange)b replacementText:(NSString *)c {
    return 0^((a.text.length+c.length<=7)+(c.length<1)+(b.length>=c.length));
}

1

Ho aperto una sottoclasse UITextField, STATextField , che offre questa funzionalità (e molto altro) con le sue maxCharacterLengthproprietà.


1

ora quanti personaggi vuoi dare solo valori

 - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range   replacementString:(NSString *)string {
     NSUInteger newLength = [textField.text length] + [string length] - range.length;
     return (newLength > 25) ? NO : YES;
  }

1

Usa questo codice qui RESTRICTED_LENGTH è la lunghezza che vuoi limitare per il campo di testo.

   - (BOOL)textField:(UITextField *)textField     shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
    if (textField == nameTF) {
    int limit = RESTRICTED_LENGTH - 1;
    return !([textField.text length]>limit && [string length] > range.length);
    }
   else
   {
    return YES;
   }

return NO;

}

1

L'ho fatto in Swift per un limite di 8 caratteri quando si utilizza un tastierino numerico.

func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
    return !(textField.text?.characters.count == MAX_LENGTH && string != "")
}

Ho dovuto testare la stringa! = "" Per consentire al pulsante Elimina di funzionare sul tastierino numerico, altrimenti non consentirebbe l'eliminazione dei caratteri nel campo di testo dopo che ha raggiunto il massimo.


1

Per Xamarin:

YourTextField.ShouldChangeCharacters = 
delegate(UITextField textField, NSRange range, string replacementString)
        {
            return (range.Location + replacementString.Length) <= 4; // MaxLength == 4
        };

1

Ho implementato un'estensione UITextField per aggiungere una proprietà maxLength ad esso.

È basato su Xcode 6 IBInspectables, quindi puoi impostare il limite maxLength sul builder Interface.

Ecco l'implementazione:

UITextField + MaxLength.h

#import <UIKit/UIKit.h>

@interface UITextField_MaxLength : UITextField<UITextFieldDelegate>

@property (nonatomic)IBInspectable int textMaxLength;
@end

UITextField + MaxLength.m

#import "UITextField+MaxLength.h"

@interface UITextField_MaxLength()

@property (nonatomic, assign) id <UITextFieldDelegate> superDelegate;

@end

@implementation UITextField_MaxLength

- (BOOL)textField:(UITextField *) textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {

    //validate the length, only if it's set to a non zero value
    if (self.textMaxLength>0) {
        if(range.length + range.location > textField.text.length)
            return NO;

        if (textField.text.length+string.length - range.length>self.textMaxLength) {
            return NO;
        }
    }

    //if length validation was passed, query the super class to see if the delegate method is implemented there
    if (self.superDelegate && [self.superDelegate respondsToSelector:@selector(textField:shouldChangeCharactersInRange:replacementString:)]) {
        return [self.superDelegate textField:textField shouldChangeCharactersInRange:range replacementString:string];
    }
    else{
        //if the super class does not implement the delegate method, simply return YES as the length validation was passed
        return YES;
    }
}

- (void)setDelegate:(id<UITextFieldDelegate>)delegate {
    if (delegate == self)
        return;
    self.superDelegate = delegate;
    [super setDelegate:self];
}

//forward all non overriden delegate methods
- (id)forwardingTargetForSelector:(SEL)aSelector {
    if ([self.superDelegate  respondsToSelector:aSelector])
        return self.superDelegate;

    return [super forwardingTargetForSelector:aSelector];
}

- (BOOL)respondsToSelector:(SEL)aSelector {
    if ([self.superDelegate respondsToSelector:aSelector])
        return YES;

    return [super respondsToSelector:aSelector];
}
@end
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.