web-dev-qa-db-de.com

Legt die maximale Zeichenlänge eines UITextFields fest

Wie kann ich die maximale Anzahl von Zeichen in einer UITextField im iPhone SDK einstellen, wenn ich eine UIView lade?

453
Domness

Während die UITextField -Klasse keine Eigenschaft für die maximale Länge hat, ist es relativ einfach, diese Funktionalität zu erhalten, indem Sie das delegate des Textfelds festlegen und die folgende Delegatmethode implementieren:

Ziel-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?.count ?? 0
    if range.length + range.location > currentCharacterCount {
        return false
    }
    let newLength = currentCharacterCount + string.count - range.length
    return newLength <= 25
}

Bevor sich das Textfeld ändert, fragt das UITextField den Delegaten, ob der angegebene Text geändert werden soll . Das Textfeld hat sich zu diesem Zeitpunkt noch nicht geändert. Daher werden die aktuelle Länge und die Länge der einzufügenden Zeichenfolge (entweder durch Einfügen von kopiertem Text oder Eingeben eines einzelnen Zeichens über die Tastatur) abzüglich der Bereichslänge ermittelt. Wenn dieser Wert zu lang ist (in diesem Beispiel mehr als 25 Zeichen), geben Sie NO zurück, um die Änderung zu verhindern.

Wenn Sie ein einzelnes Zeichen am Ende eines Textfelds eingeben, entspricht range.location der Länge des aktuellen Felds und range.length ist 0, da wir nichts ersetzen/löschen. Das Einfügen in die Mitte eines Textfelds bedeutet nur, dass ein anderer range.location und das Einfügen mehrerer Zeichen bedeutet nur, dass string mehr als ein Zeichen enthält.

Das Löschen einzelner Zeichen oder das Ausschneiden mehrerer Zeichen wird durch ein range mit einer Länge ungleich Null und eine leere Zeichenfolge angegeben. Das Ersetzen ist nur ein Löschen eines Bereichs durch eine nicht leere Zeichenfolge.

Ein Hinweis zum abstürzenden "Rückgängig" -Fehler

Wie in den Kommentaren erwähnt, gibt es einen Fehler mit UITextField, der zu einem Absturz führen kann.

Wenn Sie in das Feld einfügen, das Einfügen jedoch durch Ihre Validierungsimplementierung verhindert wird, wird der Einfügevorgang weiterhin im Rückgängig-Puffer der Anwendung aufgezeichnet. Wenn Sie dann ein Rückgängigmachen auslösen (indem Sie das Gerät schütteln und ein Rückgängigmachen bestätigen), versucht das UITextField, die Zeichenfolge zu ersetzen, die es als für sich selbst eingefügt hat, durch ein leerer String. Das wird abstürzen, weil es den String nie tatsächlich in sich selbst eingefügt hat. Es wird versucht, einen nicht vorhandenen Teil der Zeichenfolge zu ersetzen.

Glücklicherweise können Sie den UITextField davor schützen, sich selbst so umzubringen. Sie müssen nur sicherstellen, dass der zu ersetzende Bereich in der aktuellen Zeichenfolge vorhanden ist . Dies ist, was die erste Überprüfung der geistigen Gesundheit oben tut.

Swift 3.0 mit Kopieren und Einfügen funktioniert einwandfrei.

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
    }

Hoffe es ist hilfreich für dich.

1010
sickp

Danke august ( Post )

Dies ist der Code, mit dem ich am Ende gearbeitet habe:

#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
Domness

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

Edit: Speicherleckproblem behoben.

 enter image description here

45
frouo

Um die August - Antwort abzuschließen, eine mögliche Implementierung der vorgeschlagenen Funktion (siehe UITextFields Delegat ).

Ich habe domness -Code nicht getestet, aber mein Code bleibt nicht hängen, wenn der Benutzer das Limit erreicht hat. Er ist kompatibel mit einem neuen String, der einen kleineren oder gleichen ersetzt.

-(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
Jmini

Sie können dies nicht direkt tun - UITextField hat kein maxLength -Attribut, aber Sie können den UITextField's-Delegat festlegen und dann Folgendes verwenden:

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

Oft haben Sie mehrere Eingabefelder mit unterschiedlicher Länge.

- (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
Vincent

Der beste Weg wäre, eine Benachrichtigung über den sich ändernden Text einzurichten. In Ihrem -awakeFromNib Ihrer View Controller-Methode möchten Sie:

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

Dann in derselben Klasse hinzufügen:

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

Verbinden Sie dann den Ausgang myTextField mit Ihrer UITextField, und Sie können keine weiteren Zeichen hinzufügen, nachdem Sie das Limit erreicht haben. Stellen Sie sicher, dass Sie dies zu Ihrer Dealloc-Methode hinzufügen:

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

Ich habe diese UITextFieldLimit-Unterklasse erstellt:

  • Mehrere Textfelder werden unterstützt
  • Legen Sie die Begrenzung der Textlänge fest
  • Einfügen von Prävention
  • Zeigt eine Beschriftung der linken Zeichen im Textfeld an und wird ausgeblendet, wenn Sie die Bearbeitung abbrechen.
  • Animation schütteln, wenn keine Zeichen mehr übrig sind.

Holen Sie sich den UITextFieldLimit.h und UITextFieldLimit.m aus diesem GitHub-Repository:

https://github.com/JonathanGurebo/UITextFieldLimit

und fang an zu testen!

Markieren Sie Ihr vom Storyboard erstelltes UITextField und verknüpfen Sie es mithilfe des Identitätsinspektors mit meiner Unterklasse:

Identity Inspector

Dann können Sie es mit einem IBOutlet verknüpfen und das Limit festlegen (Standardeinstellung ist 10).


Ihre ViewController.h-Datei sollte Folgendes enthalten: (wenn Sie die Einstellung wie den Grenzwert ändern möchten)

#import "UITextFieldLimit.h"

/.../

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

Ihre ViewController.m-Datei sollte @synthesize textFieldLimit sein.


Legen Sie die Begrenzung der Textlänge in Ihrer ViewController.m-Datei fest:

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

Ich hoffe die Klasse hilft dir. Viel Glück!

11
Jonathan Gurebo

Dies sollte ausreichen, um das Problem zu lösen (ersetzen Sie 4 durch das Limit, das Sie wollen). Stellen Sie sicher, dass Sie einen Delegierten in IB hinzufügen.

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

Ich simuliere die tatsächliche Zeichenfolgenersetzung, die gerade ausgeführt wird, um die Länge der zukünftigen Zeichenfolge zu berechnen:

- (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
samvermette

Swift 3 Version //***** Dies funktioniert NICHT mit Swift 2.x! ***** //

Erstellen Sie zuerst eine neue Swift-Datei: TextFieldMaxLength.Swift, Und fügen Sie dann den folgenden Code hinzu:

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

in Storyboard wird dann ein neues Feld (maximale Länge) angezeigt, wenn Sie ein Textfeld auswählen

falls Sie noch weitere Fragen haben, besuchen Sie diesen Link: http://www.globalnerdy.com/2016/05/18/ios-programming-trick-how-to-use-x-code-to-set-a-text -Felder-maximal-Länge-visuell-Studio-Stil/

7
Gilad Brunfman

Der folgende Code ähnelt der Antwort von sickp, behandelt jedoch korrekt Kopier- und Einfügevorgänge. Wenn Sie versuchen, einen Text einzufügen, der länger als der Grenzwert ist, schneidet der folgende Code den Text so ab, dass er an den Grenzwert angepasst wird, anstatt den Einfügevorgang vollständig abzulehnen.

- (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
wroluk

Mit dem Interface Builder können Sie das Ereignis für "Bearbeitung geändert" in einer beliebigen Funktion verknüpfen und abrufen. __ Jetzt können Sie die Länge überprüfen

- (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
Vishal Kumar

Es gibt generische Lösung zum Einstellen der maximalen Länge in Swift . Mit IBInspectable können Sie im Xcode Attribute Inspector . neues Attribut hinzufügen 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
    }

}
5
Hiren

Damit es mit dem Ausschneiden und Einfügen von Strings beliebiger Länge funktioniert, würde ich vorschlagen, die Funktion folgendermaßen zu ändern: 

#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
Påhl Melin

Swift 2.0 +

Erstellen Sie zunächst eine Klasse für diesen Prozess. Nennen wir es StringValidator.Swift.

Dann fügen Sie einfach den folgenden Code ein.

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
}

}

Speichern Sie jetzt die Klasse .....

Verwendungszweck..

Gehen Sie jetzt zu Ihrer viewController.Swift-Klasse und erstellen Sie die Textstellen für Ihre ..

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

Gehen Sie jetzt zu der ShouldChangeCharactersInRange-Methode des Textfelds und verwenden Sie sie wie folgt.

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
    }

}

Vergessen Sie nicht, das Delegatenprotokoll/die Methoden für Textfelder festzulegen.

Lassen Sie mich das erklären ... Ich benutze den einfachen Erweiterungsprozess von string, den ich in einer anderen Klasse geschrieben habe. Jetzt rufe ich diese Erweiterungsmethoden nur aus einer anderen Klasse auf, wo ich sie brauche, indem ich check und maximum value hinzufüge.

Eigenschaften...

  1. Es wird die maximale Grenze für ein bestimmtes Textfeld festgelegt.
  2. Es legt den Typ der akzeptierten Schlüssel für ein bestimmtes Textfeld fest.

Typen ...

containsOnlyCharactersIn // Akzeptiert nur Zeichen.

containsCharactersIn // Akzeptiert eine Kombination von Zeichen

doesNotContainsCharactersIn // Nimmt keine Zeichen an

Hoffe das hat geholfen .... Danke ..

3
onCompletion

Swift 3.0

Dieser Code funktioniert einwandfrei, wenn Sie mehr Zeichen als die Zeichenbegrenzung einfügen.

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
    }

Danke für deine Stimmen. :)

3
Ilesh

Verwenden Sie unterhalb der Erweiterung, um die maximale Zeichenlänge von UITextField und UITextView festzulegen.

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

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

Sie können unten ein Limit setzen.

 enter image description here

2
Hitesh Surani

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
Shan Ye

Ich gebe eine ergänzende Antwort auf der Basis von @Frouo. Ich denke, seine Antwort ist der schönste Weg. Weil es eine gemeinsame Kontrolle ist, die wir wiederverwenden können. 

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
Victor Choy

Für Xamarin:

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

Dies ist der richtige Weg, um die maximale Länge von UITextField zu behandeln. Mit der Eingabetaste können Sie das Textfeld als Ersthelfer verlassen und den Benutzer zurücksetzen, wenn er das Limit erreicht

- (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
anders

Wenn Sie mit der Begrenzung der Textanzahl sicherstellen möchten, dass Text an anderer Stelle in ein UILabel passt, würde ich die Verwendung der Zeichenanzahl vermeiden. Bei einigen Emojis kommt es zum Absturz (der Versuch, ein Emoji mit doppelter Größe abzuschneiden, führt wahrscheinlich zum Absturz der App). Es ist auch ein Problem mit einigen Sprachen wie Japanisch und Chinesisch, die einen zweistufigen Eingabevorgang haben, bei dem eine einfache Zählung einfach nicht funktioniert. 

Ich habe eine UITextField-Drop-In-Unterklasse ( MPC_CharacterLimitedTextField für github ) erstellt. Sie füttern die erwartete Ausgabeetikettenbreite und behandeln alle Sprachen, Emoji und Einfügeprobleme. Es werden nur so viele vollständige Zeichen gesammelt, die in das Label passen, unabhängig von der Anzahl der Zeichen. Das Projekt enthält eine Demo, mit der Sie testen können, ob es das ist, was Sie brauchen. Ich hoffe, es wird jedem helfen, der die gleichen Probleme mit der Ausgabelänge hatte wie ich. 

1
Mike Critchley

Ich habe dies in Swift für ein Limit von 8 Zeichen gemacht, wenn ich einen Nummernblock verwende.

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

Ich musste auf string! = "" Testen, damit die Löschschaltfläche auf dem Nummernblock funktionieren kann. Andernfalls lassen sich Zeichen im Textfeld nicht löschen, nachdem der Maximalwert erreicht wurde.

1
u84six

nun, wie viele Zeichen Sie möchten, geben Sie nur Werte

 - (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
mahesh chowdary

Ich habe eine UITextField-Erweiterung implementiert, um eine maxLength-Eigenschaft hinzuzufügen.

Es basiert auf Xcode 6 IBInspectables. Sie können also den Grenzwert für maxLength im Interface Builder festlegen.

Hier ist die Implementierung:

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
Lefteris

Habe es bis auf eine Codezeile :)

Setzen Sie den Delegaten Ihrer Textansicht auf "self" und fügen Sie den <UITextViewDelegate> in Ihre .h und den folgenden Code in Ihre .m .... ein. Sie können die Zahl "7" so einstellen, wie Sie Ihre MAXIMALE Anzahl von Zeichen haben möchten. 

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

Dieser Code dient zum Eingeben neuer Zeichen, zum Löschen von Zeichen, zum Auswählen von Zeichen, zum Eingeben oder Löschen, zum Auswählen und Ausschneiden, zum allgemeinen Einfügen sowie zum Auswählen und Einfügen von Zeichen.

Erledigt!






Eine andere coole Möglichkeit, diesen Code mit Bitoperationen zu schreiben, wäre alternativ

-(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
Albert Renshaw

Andere Antworten behandeln nicht den Fall, in dem der Benutzer eine lange Zeichenfolge aus der Zwischenablage einfügen kann. Wenn ich eine lange Zeichenfolge einfüge, sollte sie nur abgeschnitten, aber angezeigt werden.

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
8suhas

Ich habe eine UITextField-Unterklasse, STATextField , die diese Funktionalität (und vieles mehr) mit ihrer maxCharacterLength -Eigenschaft bietet, aus einem Open-Source-Modus erstellt.

1
Stunner

Verwenden Sie diesen Code hier. RESTRICTED_LENGTH ist die Länge, die Sie für das Textfeld einschränken möchten.

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

Swift 4.2 und UITextFieldDelegate Methode

Dies funktioniert bei mir und begrenzt das Textfeld auf eine maximale Eingabe von 8 Zeichen. Hoffentlich wird NSRange irgendwann in Range geändert, aber ich bin froh, NSString verwenden zu können, da das Erstellen eines Range aus NSRange den Umgang mit einem anderen optionalen Element beinhaltet.

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    let text = textField.text ?? ""
    let nsString = text as NSString
    let newText = nsString.replacingCharacters(in: range, with: string)
    return newText.count <= 8
}
1
Edward

Was ist mit diesem einfachen Ansatz? Es funktioniert gut für mich.

extension UITextField {

    func  charactersLimit(to:Int) {

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

Dann:

someTextField.charactersLimit(to:16)
0
Joaquin Pereira

Swift 4.2 +

Durch Implementieren der Methode UITextFieldDelegate

...
let MAX_LENGTH = 256
...

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    var newText = ""
    // always zero when we add characted
    if range.length == 0 {
        newText = ((textField.text ?? "") + string).count
    } 
    // delete/cut/copy/paste character(s)
    else if var text = textField.text, let sRange = Range<String.Index>.init(range, in: text) {
        text.removeSubrange(sRange)
        text.insert(contentsOf: string, at: text.index(text.startIndex, offsetBy: range.location))
        newText = text
    }
    return newText.count < MAX_LENGTH
}
0
Pocheshire

Ich möchte die Antwort von @sickp hinzufügen.

Es gibt ein Problem in seinem Swift-Code, das bei jedem Multibyte-Text (z. B. Emojis) auftritt. NSRange und String in Swift sind nicht kompatibel. Daher ist es frustrierend, dass die Delegatklasse sie kombiniert. Der Trick besteht einfach darin, die String-Objekte in NSString zu konvertieren. Die richtige Lösung, basierend auf dem, was @sickp geschrieben hat, lautet eigentlich:

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

    let currentText = (textField.text as NSString?) ?? NSString()
    let currentCharacterCount = currentText.length
    if range.length + range.location > currentCharacterCount {
        return false
    }
    let newLength = currentText.replacingCharacters(in: range, with: string).characters.count
    return newLength <= 25
}
0
Guy Kogus

für Swift 3.1 oder höher

fügen Sie zunächst das Protokoll UITextFieldDelegate hinzu. 

mögen:-

class PinCodeViewController: UIViewController, UITextFieldDelegate { 
.....
.....
.....

}

danach erstellen Sie Ihr UITextField und setzen Sie einen Stellvertreter

Vollständige Exp: -

import UIKit

class PinCodeViewController: UIViewController, UITextFieldDelegate {

let pinCodetextField: UITextField = {
    let tf = UITextField()
    tf.placeholder = "please enter your pincode"
    tf.font = UIFont.systemFont(ofSize: 15)
    tf.borderStyle = UITextBorderStyle.roundedRect
    tf.autocorrectionType = UITextAutocorrectionType.no
    tf.keyboardType = UIKeyboardType.numberPad
    tf.clearButtonMode = UITextFieldViewMode.whileEditing;
    tf.contentVerticalAlignment = UIControlContentVerticalAlignment.center
 return tf
  }()


 override func viewDidLoad() {
   super.viewDidLoad()
   view.addSubview(pinCodetextField)
    //----- setup your textfield anchor or position where you want to show it----- 


    // after that 
pinCodetextField.delegate = self // setting the delegate

 }
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    return !(textField.text?.characters.count == 6 && string != "")
     } // this is return the maximum characters in textfield 
    }
0
kishu mewara
(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
Mubin Shaikh

Das Problem mit einigen der oben genannten Antworten ist, zum Beispiel habe ich ein Textfeld und ich muss einen Grenzwert von 15 Zeichen eingeben, der nach Eingabe des 15. Zeichens aufhört. aber sie dürfen nicht löschen. Das ist der Lösch-Button auch nicht funktionieren. Da stand ich vor dem gleichen Problem. Kam mit der Lösung, Given Below. Funktioniert perfekt für mich

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

Ich habe ein Textfeld, dessen Tag ich "6" Gesetzt habe, und ich habe die Begrenzung von max char = 30 begrenzt 

0
Jasmeet

Dies begrenzt die Anzahl der Zeichen, stellt jedoch auch sicher, dass Sie das Feld bis zum Maximalwert einfügen können.

- (void)textViewDidChange:(UITextView *)textView
{
    NSString* str = [textView text];
    str = [str substringToIndex:MIN(1000,[str length])];
    [textView setText:str];

    if([str length]==1000) {
        // show some label that you've reached the limit of 1000 characters
    }
}
0
jacklehamster

Für Swift 2.1+

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

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

    let newLength = textField.text!.characters.count + string.characters.count - range.length
    return newLength <= 25
}

Ich hoffe es hilft

0
ColossalChris

wir können den Bereich des Textfelds so einstellen.

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

Etwas jenseits der Beantwortung der ursprünglichen Frage und der Erweiterung von Frouos Antwort, hier sind Erweiterungen, um einen String mit Leerzeichen auf eine maximale Länge zuzuschneiden und diese String-Erweiterungen zu verwenden, um ein UITextField auf eine maximale Länge zu kürzen:

// In String_Extensions.Swift

extension String {

  func trimmedString() -> String {
    var trimmedString = self.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceAndNewlineCharacterSet())
    let components = trimmedString.componentsSeparatedByCharactersInSet(NSCharacterSet.whitespaceAndNewlineCharacterSet()).filter { count($0) > 0 }
    return " ".join(components)
  }

  func trimmedStringToMaxLength(maxLength: Int) -> String {
    return trimmedString().substringToIndex(advance(startIndex, min(count(self), maxLength))).trimmedString()
  }

}

// In UITextField_Extensions.Swift

private var maxLengthDictionary = [UITextField : Int]()
private var textFieldMaxLength = 20

extension UITextField {

  @IBInspectable var maxLength: Int {
    get {
      if let maxLength = maxLengthDictionary[self] {
        return maxLength
      } else {
        return textFieldMaxLength
      }
    }
    set {
      maxLengthDictionary[self] = newValue < textFieldMaxLength + 1 ? newValue : textFieldMaxLength
    }
  }

  func trimAndLimitToMaxLength() {
    text = text.trimmedStringToMaxLength(maxLength)
  }

}

let someTextField = UITextField()
let someString = "   This   is   a   string   that   is longer than allowable for a text field.   "
someTextField.text = someString
someTextField.trimAndLimitToMaxLength()
println(someTextField.text) // Prints "This is a string tha"
let anotherTextField = UITextField()
anotherTextField.maxLength = 5
anotherTextField.text = someString
anotherTextField.trimAndLimitToMaxLength()
println(anotherTextField.text) // Prints "This"

trimAndLimitToMaxLength() könnte in UITextFieldDelegates textFieldDidEndEditing(_:) verwendet werden, so dass ein Benutzer einen längeren als akzeptablen String eingeben oder einfügen und ihn dann verkürzen kann, anstatt die Eingabe bei maximaler Länge abzuschneiden. Dabei würde ich auch attributierte Textstile festlegen, um jeden Teil des Textes anzuzeigen, der über die zulässige Länge hinausgeht (z. B. [NSBackgroundColorAttributeName : UIColor.redColor(), NSForegroundColorAttributeName : UIColor.whiteColor(), NSStrikethroughStyleAttributeName : NSNumber(int: 1)]).

0
Scott Gardner

Sie können dies auch mit NotificationCenter in Swift 4 durchführen. 

NotificationCenter.default.addObserver(self, selector: #selector(self.handleTextChange(recognizer:)), name: NSNotification.Name.UITextFieldTextDidChange, object: yourTextField)

    @objc func handleTextChange(recognizer: NSNotification) {
            //max length is 50 charater max
            let textField = recognizer.object as! UITextField

            if((textField.text?.count)! > 50) {
                let newString: String? = (textField.text as NSString?)?.substring(to: 50)
                textField.text = newString

            }         
        }
0
Pramod More