Définir la longueur de caractère maximale d'un champ UITextField

comment définir le nombre maximum de caractères dans un UITextField sur le SDK iPhone quand je charge un UIView ?

447
demandé sur JasonMArcher 2009-01-11 21:08:11

30 réponses

bien que la classe UITextField n'ait pas de propriété de longueur maximale, il est relativement simple d'obtenir cette fonctionnalité en définissant le champ de texte delegate et en implémentant la méthode de délégation suivante:

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

Swift

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

    let currentCharacterCount = textField.text?.characters.count ?? 0
    if (range.length + range.location > currentCharacterCount){
        return false
    }
    let newLength = currentCharacterCount + string.characters.count - range.length
    return newLength <= 25
}

avant que le champ de texte change, L'UITextField demande au délégué si le texte spécifié devrait être remplacé par . Le champ de texte n'a pas changé à ce point, donc on saisit sa longueur actuelle et la longueur de la chaîne que nous insérons (soit en collant du texte copié ou en tapant un seul caractère au clavier), moins la longueur de l'intervalle. Si cette valeur est trop longue (plus de 25 caractères dans cet exemple), retournez NO pour interdire la modification.

en tapant un seul caractère à la fin d'un champ de texte, le range.location soit la longueur du champ courant, et range.length sera 0 parce que nous ne remplaçons/supprimons rien. Insérer au milieu d'un champ de texte signifie Juste un range.location différent , et coller plusieurs caractères signifie Juste string a plus d'un caractère en elle.

Supprimer des caractères simples ou couper des caractères multiples est spécifié par un range avec une longueur non nulle, et une chaîne vide. Le remplacement est juste une suppression de gamme avec un non vide chaîne.

note sur la panne "annuler" bug

comme mentionné dans les commentaires, il y a un bug avec UITextField qui peut conduire à un crash.

si vous collez dans le champ, mais que la pâte est empêchée par votre implémentation de validation, l'opération de collage est encore enregistrée dans le tampon de défaire de l'application. Si vous lancez alors un undo (en secouant l'appareil et en confirmant un Undo), le UITextField tentera de remplacer la chaîne pense il collé à elle-même avec une chaîne vide. Cela va planter parce qu'il n'a jamais réellement collé la corde à lui-même. Il va essayer de remplacer une partie de la chaîne qui n'existe pas.

heureusement, vous pouvez protéger le UITextField de se tuer comme ça. Vous avez juste besoin de vous assurer que la gamme qu'il propose pour remplacer ne existe dans son courant chaîne. C'est ce que la première vérification générale ci-dessus.

swift 3.0 avec la copie et la pâte de travail amende.

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
    }

J'espère que ça vous aidera.

979
répondu sickp 2018-03-26 06:30:54

merci august! ( Post )

C'est le code avec lequel j'ai fini qui fonctionne:

#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;}
}
56
répondu Domness 2017-05-23 12:10:54

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

modifier: problème de fuite de mémoire corrigé.

enter image description here

37
répondu Frouo 2018-02-06 14:29:46

complet août en réponse, une possible mise en œuvre de la fonction proposée (voir UITextField délégué du ).

Je n'ai pas testé domness code, mais le mien ne sont pas coincés si l'Utilisateur a atteint la limite, et il est compatible avec une nouvelle chaîne qui vient remplacer un plus petit ou égal.

-(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);
}
21
répondu Jmini 2009-05-07 14:00:31

vous ne pouvez pas faire cela directement - UITextField n'a pas maxlength attribut, mais vous pouvez définir le UITextField's délégué, puis utiliser:

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
17
répondu August 2014-04-14 14:37:36

souvent, vous avez plusieurs champs d'entrée avec une longueur différente.

- (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
    }
}
13
répondu Vincent 2012-09-07 07:39:45

la meilleure façon serait de mettre en place une notification sur la modification du texte. Dans votre -awakeFromNib de votre méthode de contrôleur de vue vous voulez:

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

dans la même classe, ajouter:

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

puis relier la sortie myTextField à votre UITextField et il ne vous laissera pas ajouter plus de caractères après que vous ayez atteint la limite. N'oubliez pas d'ajouter ceci à votre méthode dealloc:

[[NSNotificationCenter defaultCenter] removeObserver:self name:@"UITextFieldTextDidChangeNotification" object:myTextField];
12
répondu Martin Pilkington 2014-04-14 14:36:52

j'ai créé ce UITextFieldLimit sous-classe:

  • Plusieurs objets textfield pris en charge
  • fixe la limite de longueur du texte
  • Coller "prévention de la 1519110920"
  • affiche une étiquette de caractères gauches à l'intérieur du champ text, se cache lorsque vous arrêtez d'éditer.
  • Shake animation lorsque aucun des caractères de gauche.

Saisir l' UITextFieldLimit.h et UITextFieldLimit.m de ce dépôt GitHub:

https://github.com/JonathanGurebo/UITextFieldLimit

et commencez à tester!

marquez votre UITextField créé par storyboard et liez-le à ma sous-classe en utilisant L'Inspecteur D'identité:

Identity Inspector

alors vous pouvez le lier à un IBOutlet et définir la limite(par défaut est 10).


Votre ViewController.h fichier doit contenir: (si vous voulez pas modifier le paramètre, comme la limite)

#import "UITextFieldLimit.h"

/.../

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

Votre ViewController.m fichier doit @synthesize textFieldLimit .


définissez la limite de longueur de texte dans votre ViewController.m fichier:

- (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.
}

J'espère que la classe vous aidera. Bonne chance!

11
répondu Jonathan Gurebo 2014-04-20 18:25:32

cela devrait suffire à résoudre le problème (remplacer 4 par la limite souhaitée). Il suffit de s'assurer d'ajouter délégué en IB.

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
     NSString *newString = [textField.text stringByReplacingCharactersInRange:range withString:string];
     return (newString.length<=4);
}
11
répondu Nishant 2015-09-08 08:39:37

je simule le remplacement réel de la chaîne qui est sur le point d'arriver pour calculer la longueur de la chaîne future:

- (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
répondu samvermette 2011-07-28 04:58:48

version Swift 3 // * * * * * * Cela ne fonctionnera pas avec Swift 2.x! ***** / /

créez D'abord un nouveau fichier Swift : TextFieldMaxLength.Swift, et puis ajouter le code ci-dessous:

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

et ensuite vous verrez dans Storyboard un nouveau champ (Longueur maximale) lorsque vous sélectionnez un champ de texte

si vous avez encore des questions, consultez le lien suivant: http://www.globalnerdy.com/2016/05/18/ios-programming-trick-how-to-use-xcode-to-set-a-text-fields-maximum-length-visual-studio-style /

7
répondu Gilad Brunfman 2016-09-29 15:36:46

en utilisant Interface builder vous pouvez lier et obtenir l'événement pour" Édition modifié " dans n'importe laquelle de vos fonctions. Maintenant là vous pouvez mettre le chèque pour la longueur

- (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
répondu Vishal Kumar 2010-09-16 08:35:52

le code suivant est similaire à la réponse de sickp mais gère correctement les opérations de copier-coller. Si vous essayez de coller un texte qui est plus long que la limite, le code suivant va tronquer le texte à la limite, au lieu de refuser l'opération de collage complètement.

- (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
répondu wroluk 2014-08-12 08:02:52

pour le faire fonctionner avec cut & paste de cordes de n'importe quelle longueur, je suggérerais de changer la fonction à quelque chose comme:

#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;
        }
    }
5
répondu Påhl Melin 2009-10-13 09:15:19

il y a " generic solution pour fixer la longueur maximale dans Swift. Par IBInspectable vous pouvez ajouter un nouvel attribut dans Xcode attribut Inspector. enter image description here

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
    }

}
4
répondu Hiren 2016-08-11 12:17:26

Swift 2.0 +

tout d'Abord créer une classe pour ce processus. Appelons-le StringValidator.Swift.

alors il suffit de coller le code suivant à l'intérieur.

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
}

}

sauvez maintenant la classe.....

"151940920 d'Utilisation"..

maintenant, allez dans votre viewController.la classe swift et faites vos points de vente textfield as..

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

maintenant, allez à la méthode textfield's shouldChangeCharactersInRange et utilisez comme suit.

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
    }

}

n'oubliez pas de définir le protocole délégué/les méthodes de textfields.

laissez-moi vous expliquer... J'utilise le simple processus d'extension de string que j'ai écrit dans une autre classe. Maintenant, je ne fais qu'appeler ces méthodes d'extension d'une autre classe où j'en ai besoin en ajoutant contrôle et valeur maximale.

Features...

  1. il fixera la limite maximale d'un champ de texte particulier.
  2. il définira le type de touches acceptées pour un champ de texte particulier.

...

containsOnlyCharactersIn / / N'accepte que les caractères.

containsCharactersIn //Accepte combinaison de caractères

doesNotContainsCharactersIn //ne Sera pas accepter les caractères

Espère que cela a aidé.... Grâce..

3
répondu onCompletion 2016-10-31 12:24:14

swift 3.0

ce code fonctionne bien quand vous collez de la chaîne plus que vos limites de caractères.

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
    }

Merci pour vos votes. :)

3
répondu ilesh 2016-12-29 13:35:44

c'est la bonne façon de gérer la longueur maximale sur UITextField, cela permet à la touche de retour de quitter le textfield en tant que premier répondant et permet à l'utilisateur de revenir en arrière quand ils atteignent la 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
répondu anders 2013-09-23 15:30:17

Pour Xamarin:

YourTextField.ShouldChangeCharacters = 
delegate(UITextField textField, NSRange range, string replacementString)
        {
            return (range.Location + replacementString.Length) <= 4; // MaxLength == 4
        };
2
répondu Kedu 2016-03-01 13:41:09

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
}
2
répondu Shan Ye 2018-02-09 17:07:15

autres réponses ne gèrent pas le cas où l'utilisateur peut coller une longue chaîne de caractères à partir du presse-papiers. Si je colle une longue chaîne, elle doit être tronquée mais affichée. Utilisez ceci dans votre délégué:

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
répondu 8suhas 2013-04-04 05:39:20

Eu 1 ligne de code :)

définissez le délégué de votre vue texte à" self "puis ajoutez le <UITextViewDelegate> dans votre .h et le code suivant dans votre .m. ... vous pouvez ajuster le nombre " 7 " pour être celui que vous voulez que votre nombre MAXIMUM de caractères soit.

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

ce code permet de taper de nouveaux caractères, de supprimer des caractères, de sélectionner des caractères puis de taper ou de supprimer, de sélectionner des caractères et de couper, de coller en général, et la sélection des caractères et le collage.

fait!










alternativement, une autre façon cool d'écrire ce code avec des opérations bit serait

-(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
répondu Albert Renshaw 2013-12-13 06:22:41

j'ai open sourced une sous-classe UITextField, STATextField , qui offre cette fonctionnalité (et beaucoup plus) avec sa propriété maxCharacterLength .

1
répondu Stunner 2015-06-17 01:02:34

maintenant combien de caractères vous voulez juste donner des valeurs

 - (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
répondu mahesh chowdary 2015-09-08 08:40:04

utilisez ce code ici RESTRICTED_LENGTH est la longueur que vous voulez restreindre pour textfield.

   - (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
répondu Amit Shelgaonkar 2015-12-18 17:43:48

j'ai fait cela dans Swift pour une limite de 8 caractères lorsque j'ai utilisé un pavé numérique.

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

j'ai dû tester la corde != ""pour permettre au bouton Supprimer de fonctionner sur le bloc de nombres, sinon il ne permettrait pas de supprimer des caractères dans le champ de texte après qu'il ait atteint son maximum.

1
répondu u84six 2016-01-20 20:06:40

j'ai implémenté une Extension UITextField pour y ajouter une propriété maxLength.

il est basé sur Xcode 6 IBInspectables, donc vous pouvez définir la limite de maxLength sur le constructeur de L'Interface.

Voici la mise en œuvre:

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
1
répondu Lefteris 2016-06-05 21:56:45

je donne une réponse supplémentaire basée sur @Frouo. Je pense que sa réponse est la plus belle manière. Parce que c'est un contrôle commun qu'on peut réutiliser.

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
    }

}
1
répondu Victor Choy 2018-02-06 12:51:21

le problème avec une partie de la réponse donnée ci-dessus est, par exemple, j'ai un champ de texte et je dois définir une limite de 15 caractères, puis il s'arrête après avoir entré 15 caractères. mais ils Ne permettent pas de supprimer. C'est le bouton supprimer ne fonctionne pas. Comme je faisais face au même problème. Est sorti avec la solution , donnée ci-dessous. Fonctionne parfait pour moi

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
 if(textField.tag==6)
 {
    if ([textField.text length]<=30)
    {
        return YES;   
    }
    else if([@"" isEqualToString:string])
    {
        textField.text=[textField.text substringToIndex:30 ];
    }

    return NO;
 }
 else
 {
    return YES;
 }
}

j'ai un champ de texte, dont j'ai placé l'étiquette " 6" et j'ai restreint la limite de char max = 30 ; fonctionne très bien dans tous les cas

0
répondu Jasmeet 2014-03-21 14:36:40
(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
    NSString *newString = [textField.text stringByReplacingCharactersInRange:range withString:string];

    if ([txt_name.text length]>100)
    {
        return NO;
    }

    return YES;
}
0
répondu Mubin Shaikh 2014-05-19 14:48:47