Legen Sie die maximale Zeichenlänge eines UITextField fest

Antworten:

1029

Obwohl die UITextFieldKlasse keine Eigenschaft für die maximale Länge hat, ist es relativ einfach, diese Funktionalität zu erhalten, indem Sie die Textfelder festlegen delegateund die folgende Delegatenmethode 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;
}

Schnell

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 das Textfeld ändert, fragt der UITextField die Delegaten , wenn der angegebene Text soll geändert werden. Das Textfeld hat sich zu diesem Zeitpunkt nicht geändert, daher ermitteln wir die aktuelle Länge und die Länge der Zeichenfolge, die wir einfügen (entweder durch Einfügen von kopiertem Text oder durch Eingabe eines einzelnen Zeichens über die Tastatur), abzüglich der Bereichslänge. Wenn dieser Wert zu lang ist (in diesem Beispiel mehr als 25 Zeichen), kehren Sie zurück NO, um die Änderung zu verhindern.

Wenn Sie ein einzelnes Zeichen am Ende eines Textfelds eingeben, range.locationist dies die Länge des aktuellen Felds und range.length0, da wir nichts ersetzen / löschen. Das Einfügen in die Mitte eines Textfelds bedeutet nur ein anderes range.locationZeichen, und das Einfügen mehrerer Zeichen bedeutet nur, dass stringmehr als ein Zeichen enthalten ist.

Das Löschen einzelner Zeichen oder das Ausschneiden mehrerer Zeichen wird durch a rangemit einer Länge ungleich Null und einer leeren Zeichenfolge angegeben. Das Ersetzen ist nur eine Bereichslöschung durch eine nicht leere Zeichenfolge.

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

Wie in den Kommentaren erwähnt, gibt es einen Fehler 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 eine Undo - Feuer (durch Schütteln des Geräts und eine Undo - Bestätigung), die UITextFieldversucht, die Zeichenfolge zu ersetzen es denkt , dass es in sich mit einem leeren String eingefügt. Dies wird abstürzen , weil es nie wirklich die Zeichenfolge in an sich selbst geklebt. Es wird versucht, einen Teil der Zeichenfolge zu ersetzen, der nicht vorhanden ist.

Glücklicherweise können Sie die vor dem UITextFieldTöten selbst so schützen . Sie müssen nur sicherstellen , dass der Bereich schlägt sie zu ersetzen tut exist in seinem aktuellen String. Dies ist, was die obige anfängliche Überprüfung der geistigen Gesundheit bewirkt.

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.

sickp
quelle
7
Finden Sie eine Lösung, indem Sie diese beiden Zeilen mit if (textField == _ssn) {} umgeben und return YES hinzufügen. am Ende der Methode, mit der alle anderen UITextFields Text ohne Einschränkung akzeptieren können. Raffiniert!
Kyle Clegg
55
Gute Antwort, aber der ternäre Operator ist überflüssig; Sie könnten einfach setzenreturn newLength <= 25;
Jowie
2
Was ist, wenn der Text nur nicht über den Rahmen des Textfelds gelangen soll? Nicht alle Zeichen sind gleich breit, oder?
Morkrom
2
Es gibt wirklich einen Rückgängig-Fehler, wie @bcherry erwähnt - getestet mit UITextFieldauf iPad iOS 8.1. (+1 zum Kommentieren). Würde der Autor etwas dazu hinzufügen, da dies die am besten bewertete Antwort ist? Ich mache gerne eine Bearbeitung, aber meine scheinen regelmäßig abgelehnt zu werden! :-)
Benjohn
8
@bherry In Swift scheint die Prüfung auf den Fall des Rückgängigmachens den Eintrag von Emoji zu unterbrechen. Sollte die Anzahl (textField.text) nicht tatsächlich count (textField.text.utf16) sein, um mit der objc / uikit-Berichterstattung im Bereich übereinzustimmen (im Vergleich zu Swifts Variante der Anzahl der Zeichenfolgen)?
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
    }
}

Bearbeiten: Speicherverlust behoben.

Geben Sie hier die Bildbeschreibung ein

frouo
quelle
Tolle Idee Frouo! Ich habe es in meiner Antwort erweitert, um das maxLength-Trimmen in eine String-Erweiterung zu verschieben, damit es auch für Dinge wie UITextView-Instanzen verwendet werden kann, und um eine praktische Funktion hinzuzufügen, um diese String-Erweiterungen in einer UITextField-Erweiterung zu nutzen.
Scott Gardner
1
Erzeugt diese globale Variable nicht Speicherlecks, indem sie Verweise auf alle Textansichten enthält (die bis zum Root- auf die Superviews verweisen)
Ixx
3
@Ixx Ich habe bearbeitet, um das Speicherleck-Problem zu beheben, auf das Sie hingewiesen haben + schnell 3. Danke
frouo
1
der schönste Weg, es zu erreichen! Vielen Dank
Victor Choy
kann mir jemand seine objektive Version zur Verfügung stellen
MRizwan33
56

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;}
}
Domness
quelle
19
Leider kann diese Lösung das Kopieren und Einfügen von Benutzern in ein Textfeld nicht stoppen, sodass sie das Limit umgehen können. Die Antwort von Sickpea kommt mit dieser Situation richtig zurecht.
Ameise
5
Was ist mit Leuten, die eine if-Anweisung haben, NEIN oder JA zurückzugeben? Versuchen Sie Folgendes: return! (TextField.text.length> = MAX_LENGTH && range.length == 0);
Matt Parkins
oder diesreturn textField.text.length < MAX_LENGTH || range.length != 0;
igrek
22

Um die Antwort vom August zu vervollständigen , eine mögliche Implementierung der vorgeschlagenen Funktion (siehe Delegierter von UITextField ).

Ich habe den Domness- Code nicht getestet , aber meiner bleibt nicht hängen , wenn der Benutzer das Limit erreicht hat, und er ist mit einer neuen Zeichenfolge kompatibel, die eine kleinere oder gleichwertige 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);
}
Jmini
quelle
17

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

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
August
quelle
5
Ich stimme zu, dies ist der beste Weg nach vorne, aber es bleibt ein bisschen ein Hack. Senden Sie einen Fehlerbericht an Apple, in dem eine Eigenschaft für die Textlänge angezeigt werden soll. Das interessiert mich definitiv auch.
Avocade
5
@avocade, es ist kein Hack: Es ist ein Beispiel, in dem Sie grundlegenden Framework-Code erstellen müssen, den Apple für Sie hätte tun sollen. Es gibt VIELE Beispiele dafür im iOS SDK.
Dan Rosenstark
13

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
    }
}
Vincent
quelle
12

Der beste Weg wäre, eine Benachrichtigung über die Textänderung einzurichten. In Ihrer -awakeFromNibView 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 myTextFieldmit Ihrem UITextFieldund 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];
Martin Pilkington
quelle
Obwohl ich dies getan habe, um Fehler zu entfernen> myTextField.text = [myTextField.text substringToIndex: limit];
Luke
11

Ich habe diese UITextFieldLimit-Unterklasse erstellt:

  • Mehrere Textfelder werden unterstützt
  • Legen Sie die Textlängenbegrenzung fest
  • Pastenprävention
  • Zeigt eine Beschriftung der linken Zeichen im Textfeld an. Wird ausgeblendet, wenn Sie die Bearbeitung beenden.
  • Schütteln Sie die Animation, wenn keine Zeichen mehr vorhanden sind.

Holen Sie sich das UITextFieldLimit.hund UITextFieldLimit.maus 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 mit dem Identitätsinspektor mit meiner Unterklasse:

Identitätsinspektor

Anschließend können Sie es mit einem IBOutlet verknüpfen und das Limit festlegen (Standard ist 10).


Ihre ViewController.h-Datei sollte Folgendes enthalten: (wenn Sie die Einstellung nicht ändern möchten, z. B. das Limit)

#import "UITextFieldLimit.h"

/.../

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

Ihre ViewController.m-Datei sollte @synthesize textFieldLimit.


Legen Sie die Textlängenbeschränkung 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.
}

Hoffe die Klasse hilft dir. Viel Glück!

Jonathan Gurebo
quelle
Für die geringe Notwendigkeit der Zeichenbeschränkung denke ich, dass das Hinzufügen Ihrer Klasse einfach übertrieben wäre.
Domness
Trotzdem Mühe geschätzt.
Reaper
11

Dies sollte ausreichen, um das Problem zu lösen (ersetzen Sie 4 durch das gewünschte Limit). Stellen Sie einfach sicher, dass Sie einen Delegaten 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);
}
Nishant
quelle
9

Verwenden Sie die folgende Erweiterung, um die maximale Zeichenlänge von a UITextFieldund festzulegen 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
        }
    }

Sie können das Limit unten festlegen.

Geben Sie hier die Bildbeschreibung ein

COVID-19
quelle
beste Antwort bei weitem ,,, vielen Dank großartige Lösung, wenn es viele Textfelder gibt, die unterschiedliche Längen benötigen
Carlos Norena
Wirklich großartige Lösung für die Eingabebeschränkung für Textfeld- und Textansicht-Steuerzeichen. Es ist sicher, Codezeilen und Zeit auch für Entwickler ... :)
Sandip Patel - SM
Dies funktioniert besser als die anderen Lösungen, die ich gefunden habe. Wenn Sie beispielsweise Emojis in Ihrem Textfeld haben, werden andere Erweiterungen, die ich gefunden habe, beim Bearbeiten am Ende der Zeile angezeigt. Aber Ihr Code macht das nicht. Vielen Dank!
Phontaine Judd
7

Ich simuliere den tatsächlichen String-Austausch, der passieren wird, um die Länge des zukünftigen Strings 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;
}
Samvermette
quelle
7

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

und dann sehen Sie im Storyboard ein neues Feld (Max Length), wenn Sie ein TextField auswählen

Wenn Sie noch weitere Fragen haben, besuchen Sie diesen Link: http://www.globalnerdy.com/2016/05/18/ios-programming-trick-how-to-use-xcode-to-set-a-text-fields -maximum-length-visual-studio-style /

Gilad Brunfman
quelle
Warnung: Diese globale Variable führt zu Speicherlecks, indem Verweise auf alle Textansichten gespeichert werden.
Frouo
6

Mit dem Interface Builder können Sie das Ereignis für "Bearbeiten geändert" in einer beliebigen Ihrer Funktionen verknüpfen und abrufen. Jetzt können Sie dort 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;
    }

}
Vishal Kumar
quelle
6

Der folgende Code ähnelt der Antwort von sickp, behandelt jedoch das Kopieren und Einfügen korrekt. Wenn Sie versuchen, einen Text einzufügen, der länger als das Limit ist, schneidet der folgende Code den Text so ab, dass er dem Limit entspricht, 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;
    }
}
wroluk
quelle
6

Es gibt eine generische Lösung zum Festlegen der maximalen Länge in Swift. Mit IBInspectable können Sie im Xcode Attribute Inspector ein neues Attribut hinzufügen.Geben Sie hier die Bildbeschreibung ein

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
    }

}
Hiren
quelle
Saubere und perfekte Lösung
Eduardo
Wenn Sie ein UITextField in einem globalen Feld halten, bleiben diese im Speicher, auch nachdem der UIViewController geschlossen wurde. Dies ist ein Speicherverlust. Verwenden Sie diese Methode nicht.
Gunhan
5

Damit es mit dem Ausschneiden und Einfügen von Zeichenfolgen beliebiger Länge funktioniert, würde ich vorschlagen, die Funktion wie folgt 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;
        }
    }
Påhl Melin
quelle
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
}
Shan Ye
quelle
Warum das guard?
oddRaven
Überprüfen Sie, ob der Text Null ist. Wenn Sie möchten, können Sie auch verwenden, wenn @oddRaven
Shan Ye
3

Swift 2.0 +

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

Fügen Sie dann 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 machen Sie die Outlets Ihres Textfelds zu ..

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

Gehen Sie nun zur Methode shouldChangeCharactersInRange 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 verwende den einfachen Erweiterungsprozess von Zeichenfolgen, den ich in einer anderen Klasse geschrieben habe. Jetzt rufe ich nur diese Erweiterungsmethoden aus einer anderen Klasse auf, in der ich sie benötige, indem ich check und den Maximalwert hinzufüge.

Eigenschaften...

  1. Es wird die maximale Grenze eines bestimmten Textfelds festgelegt.
  2. Es wird der Typ der akzeptierten Schlüssel für ein bestimmtes Textfeld festgelegt.

Typen ...

enthältOnlyCharactersIn // Akzeptiert nur Zeichen.

enthältCharactersIn // Akzeptiert eine Kombination von Zeichen

doesNotContainsCharactersIn // Akzeptiert keine Zeichen

Hoffe das hat geholfen .... Danke ..

bei Fertigstellung
quelle
3

schnell 3.0

Dieser Code funktioniert einwandfrei, wenn Sie Zeichenfolgen mehr als Ihre Zeichenbeschränkungen 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. :) :)

Ilesh P.
quelle
2
UITextField, nicht UITextView.
Jonny
3

Ich gebe eine ergänzende Antwort basierend auf @Frouo. Ich denke, seine Antwort ist der schönste Weg. Weil es eine übliche 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
    }

}
Victor Choy
quelle
2

Dies ist die richtige Methode, um die maximale Länge in UITextField zu verarbeiten. Sie ermöglicht es der Eingabetaste, das Textfeld als Ersthelfer zu verlassen, und lässt den Benutzer die Rücktaste zurück, 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;
    }
}
anders
quelle
2

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)
Joaquin Pereira
quelle
1

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. Verwenden Sie dies in Ihrem Delegaten:

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'

}
8suhas
quelle
1

Habe es auf 1 Codezeile reduziert :)

Setzen Sie den Delegaten <UITextViewDelegate>Ihrer Textansicht auf "self" und fügen Sie dann den Code in Ihrer .h und den folgenden Code in Ihre .m ein. Sie können die Zahl "7" so einstellen, dass sie der gewünschten maximalen Zeichenanzahl entspricht.

-(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 berücksichtigt das Eingeben neuer Zeichen, das Löschen von Zeichen, das Auswählen von Zeichen, das anschließende Eingeben oder Löschen, das Auswählen von Zeichen und das Ausschneiden, das Einfügen im Allgemeinen sowie das Auswählen von Zeichen und das Einfügen.

Erledigt!






Alternativ wäre eine andere coole Möglichkeit, diesen Code mit Bitoperationen zu schreiben

-(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));
}
Albert Renshaw
quelle
1

Ich habe eine UITextField-Unterklasse, STATextField , als Open-Source-Version bereitgestellt , die diese Funktionalität (und vieles mehr) mit ihrer maxCharacterLengthEigenschaft bietet .

Stunner
quelle
1

Nun, wie viele Zeichen du willst, gib nur Werte an

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

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;

}
Amit Shelgaonkar
quelle
1

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

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 Schaltfläche "Löschen" auf dem Nummernblock funktioniert, da sonst das Löschen von Zeichen im Textfeld nach Erreichen des Maximums nicht mehr möglich ist.

u84six
quelle
1

Für Xamarin:

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

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

Es basiert auf Xcode 6 IBInspectables, sodass Sie das maxLength-Limit im Interface Builder festlegen können.

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
Lefteris
quelle