De maximale tekenlengte een UITextField

stemmen
439

Hoe kan ik het maximum aantal tekens in een UITextFieldop de iPhone SDK wanneer ik laden een UIView?

De vraag is gesteld op 11/01/2009 om 19:08
bron van user
In andere talen...                            


44 antwoorden

stemmen
970

Terwijl de UITextFieldklasse heeft geen maximale lengte bezit, is het relatief eenvoudig om deze functionaliteit te krijgen door het instellen van het tekstveld's delegateen de uitvoering van de volgende delegate methode:

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

Snel

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
}

Voordat het tekstveld verandert, de UITextField vraagt de afgevaardigde als de opgegeven tekst moet worden veranderd. Het tekstveld is niet veranderd op dit punt, dus we pakken het huidige lengte en de lengte van het touw dat we het invoegen (hetzij door middel van plakken gekopieerde tekst of het typen van een enkel teken via het toetsenbord), minus de range lengte. Als deze waarde te lang (meer dan 25 tekens in dit voorbeeld) terug NOom de wijziging te verbieden.

Tijdens het intoetsen van een enkel teken aan het einde van een tekstveld, het range.locationzal de lengte van het huidige veld, en range.length0 zal zijn omdat we niet te vervangen / niet wilt wissen. Inbrengen in het midden van een tekstveld betekent gewoon een ander range.location, en plakken van meerdere tekens betekent gewoon stringmeer dan een teken in.

Losse letters verwijderen of uitsnijden meerdere tekens wordt gespecificeerd door een rangemet een niet-nul lengte en een lege string. Vervanging is slechts een bereik wissen met een niet-lege string.

Een opmerking over het crashen "ongedaan maken" bug

Zoals in de antwoorden wordt vermeld, is er een bug met UITextFielddie kan leiden tot een crash.

Als u plakken in het veld, maar de pasta wordt voorkomen door uw validatie implementatie wordt de pasta operatie nog opgenomen in undo-buffer van de toepassing. Als u vervolgens het vuur een undo (door het schudden van het apparaat en de bevestiging van een Undo), het UITextFieldzal proberen om de string te vervangen denkt deze geplakt in om zich met een lege string. Dit zal crashen omdat het nooit echt de string geplakt aan zichzelf. Het zal proberen om een deel van de string die niet bestaat te vervangen.

Gelukkig kunt u het beschermen UITextFieldvan zichzelf te doden als deze. Je hoeft alleen maar om ervoor te zorgen dat het bereik zij voornemens is te vervangen heeft bestaan in zijn huidige string. Dit is wat de initiële sanity check bovenstaande doet.

swift 3.0 met kopiëren en plakken werkt prima.

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
    }

Hoop dat het nuttig voor u.

antwoordde op 20/11/2009 om 22:10
bron van user

stemmen
56

Dank je wel augustus! ( Bericht )

Dit is de code die ik eindigde met die werkt:

#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;}
}
antwoordde op 11/01/2009 om 20:40
bron van user

stemmen
29

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

Edit: geheugenlek probleem opgelost.

voer image beschrijving hier

antwoordde op 22/04/2015 om 16:56
bron van user

stemmen
21

Om te voltooien augustus antwoord, een mogelijke implementatie van de voorgestelde functie (zie UITextField afgevaardigde ).

Ik heb het niet getest domness code, maar de mijne niet vast komen te zitten als de gebruiker de limiet bereikt, en het is compatibel met een nieuwe string die komt ter vervanging van een kleiner of gelijk is aan één.

-(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);
}
antwoordde op 16/04/2009 om 08:51
bron van user

stemmen
17

U kunt dit niet direct doen - UITextFieldheeft geen maxLength attribuut, maar u kunt het instellen UITextField'sdelegeren, gebruik dan:

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
antwoordde op 11/01/2009 om 19:42
bron van user

stemmen
13

Vaak heb je meerdere invoervelden met een andere lengte.

- (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
    }
}
antwoordde op 07/09/2012 om 08:39
bron van user

stemmen
12

De beste manier zou zijn om het opzetten van een melding op de tekst te veranderen. In je -awakeFromNibvan uw visie controller methode die u zult willen:

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

Toen in dezelfde klasse toe te voegen:

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

Koppelen vervolgens het stopcontact myTextFieldom uw UITextFielden het zal niet toestaan dat u meer tekens toevoegen nadat u de limiet bereikt. Zorg ervoor dat u deze toe te voegen aan uw dealloc methode:

[[NSNotificationCenter defaultCenter] removeObserver:self name:@"UITextFieldTextDidChangeNotification" object:myTextField];
antwoordde op 11/01/2009 om 20:19
bron van user

stemmen
11

Ik creëerde dit UITextFieldLimit subklasse:

  • Meerdere tekstvelden ondersteund
  • Tekstopties limiet
  • paste preventie
  • Hiermee wordt een label van linkse tekens in het tekstveld, krijg verborgen wanneer u stopt met het uitgeven.
  • Schud animatie wanneer er geen tekens over.

Pak de UITextFieldLimit.hen UITextFieldLimit.mvan deze GitHub repository:

https://github.com/JonathanGurebo/UITextFieldLimit

en beginnen te testen!

Markeer uw-storyboard gemaakt UITextField en te koppelen aan mijn subklasse met behulp van de Identity Inspector:

Identity Inspector

Dan kunt u deze koppelen aan een IBOutlet en stel de limiet (standaard is 10).


Uw ViewController.h bestand moet bevatten: (als u wan't om de instelling te wijzigen, zoals de limiet)

#import "UITextFieldLimit.h"

/.../

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

Uw ViewController.m bestand moet @synthesize textFieldLimit.


Stel de tekst lengte limiet in uw ViewController.m file:

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

Hoop dat de klas helpt u. Succes!

antwoordde op 12/04/2014 om 23:37
bron van user

stemmen
10

Dit moet genoeg zijn om het probleem (vervang 4 Door de limiet u wilt) op te lossen. Zorg er wel voor te delegeren IB toe te voegen.

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
     NSString *newString = [textField.text stringByReplacingCharactersInRange:range withString:string];
     return (newString.length<=4);
}
antwoordde op 20/08/2012 om 11:10
bron van user

stemmen
7

Swift 3-versie // ***** Dit zal niet werken met Swift 2.x! ***** //

Maak eerst een nieuw Swift file: TextFieldMaxLength.swift, en voeg dan de onderstaande code:

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

en dan zul je zien in Storyboard een nieuw veld (Max lengte) wanneer u een tekstveld selecteert

Als u nog meer vragen kijk op deze link: http://www.globalnerdy.com/2016/05/18/ios-programming-trick-how-to-use-xcode-to-set-a-text-fields -Maximale-length-visual-studio-stijl /

antwoordde op 29/09/2016 om 15:28
bron van user

stemmen
7

Ik simuleren de werkelijke snaar vervanger die er gaat gebeuren op lengte dat de toekomstige snaar te berekenen:

- (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;
}
antwoordde op 28/07/2011 om 05:58
bron van user

stemmen
6

De volgende code is vergelijkbaar met het antwoord sickp maar handgrepen correct copy-paste operaties. Als u probeert om een ​​tekst die langer is dan de limiet te plakken, zal de volgende code de tekst inkorten tot de limiet in plaats passen van de pasta operatie volledig te weigeren.

- (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;
    }
}
antwoordde op 12/08/2014 om 09:02
bron van user

stemmen
6

Met behulp van Interface Builder u kunt koppelen en krijgen het evenement "Editing veranderd" in een van uw functie. Nu is er dan kunt u check zetten voor de duur

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

}
antwoordde op 16/09/2010 om 09:35
bron van user

stemmen
5

Om het te laten werken met knippen en plakken van de snaren van elke lengte, stel ik voor het veranderen van de functie om iets als:

#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;
        }
    }
antwoordde op 13/10/2009 om 08:34
bron van user

stemmen
4

Er is generieke oplossing voor het instellen van maximale lengte in Swift. Door IBInspectable kunt u nieuwe attribuut in Xcode Attribute Inspector toe te voegen.voer image beschrijving hier

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
    }

}
antwoordde op 11/08/2016 om 12:17
bron van user

stemmen
3

swift 3.0

Deze code werkt prima als je pasta snaar meer dan je karakter grenzen.

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
    }

Bedankt voor uw stem. :)

antwoordde op 29/12/2016 om 13:35
bron van user

stemmen
3

Swift 2.0 +

Allereerst is het creëren van een klasse voor dit proces. Laten we noemen het StringValidator.swift.

Dan gewoon plak de volgende code erin.

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
}

}

Sla nu de klas .....

Gebruik..

Ga nu naar uw viewController.swift klasse en maak verkooppunten van uw tekstveld als ..

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

Ga nu naar het tekstveld's shouldChangeCharactersInRange methode en gebruiken, zoals het volgende.

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
    }

}

Vergeet niet om de gemachtigde protocol / methoden van tekstvelden in te stellen.

Laat me uitleggen over dit ... Ik gebruik de eenvoudige uitbreiding proces van de string die ik schreef in een andere klasse. Nu ben ik alleen maar bellen die extension methods uit een andere groep waar ik moet ze door het toevoegen van controle en maximale waarde.

Kenmerken...

  1. Het zal maximum van een bepaald tekstveld in te stellen.
  2. Het zal soort van geaccepteerde sleutels voor bepaalde tekstveld in te stellen.

Types...

containsOnlyCharactersIn // accepteert alleen tekens.

containsCharactersIn // accepteert combinatie van tekens

doesNotContainsCharactersIn // Zal niet tekens accepteren

Hoop dat dit heeft geholpen .... Thanks ..

antwoordde op 27/11/2015 om 18:51
bron van user

stemmen
3

Dit is de juiste manier om maximale lengte op UITextField te behandelen, is het mogelijk de Return-toets om af te sluiten het aftreden het tekstveld als first responder en laat de gebruiker backspace wanneer zij de limiet bereikt

- (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;
    }
}
antwoordde op 23/09/2013 om 16:30
bron van user

stemmen
2

Voor Xamarin:

YourTextField.ShouldChangeCharacters = 
delegate(UITextField textField, NSRange range, string replacementString)
        {
            return (range.Location + replacementString.Length) <= 4; // MaxLength == 4
        };
antwoordde op 01/03/2016 om 13:41
bron van user

stemmen
1

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
}
antwoordde op 09/02/2018 om 17:07
bron van user

stemmen
1

Ik deed dit in Swift voor een 8 tekens bij gebruik van een numeriek toetsenbord.

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

Ik moest om te testen voor strijkkwartet! = "" Om de delete-knop om te werken op het numerieke toetsenblok, anders zou het niet toestaan ​​dat het verwijderen van tekens in het tekstveld nadat zij haar maximum bereikt.

antwoordde op 20/01/2016 om 20:06
bron van user

stemmen
1

Gebruik deze code hier RESTRICTED_LENGTH is de lengte u wilt beperken voor het tekstveld.

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

}
antwoordde op 30/09/2015 om 10:36
bron van user

stemmen
1

Ik heb open source een UITextField subklasse STATextField , die deze functionaliteit (en nog veel meer) met zijn biedt maxCharacterLengtheigendom.

antwoordde op 17/06/2015 om 01:02
bron van user

stemmen
1

Ik heb een UITextField Uitbreiding uitgevoerd om een ​​maxLength woning toe te voegen.

Het is gebaseerd op Xcode 6 IBInspectables, zodat u de limiet maxLength op de Interface Builder kunt instellen.

Hier is de implementatie:

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
antwoordde op 28/11/2014 om 17:48
bron van user

stemmen
1

Begrepen tot 1 regel code :)

Stel afgevaardigde uw tekstweergave om "zelf" en voeg dan de <UITextViewDelegate>in uw .h en de volgende code in uw .m .... U kunt het nummer "7" aan te passen aan zijn wat u wilt dat uw maximum aantal tekens te zijn.

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

Deze code is goed voor het typen van nieuwe personages, het verwijderen van karakters, tekens selecteren vervolgens te typen of te verwijderen, het selecteren van personages en knippen, plakken in het algemeen, en het selecteren van karakters en plakken.

Gedaan!






Als alternatief, een andere coole manier om deze code te schrijven met bit-operaties zou zijn

-(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));
}
antwoordde op 13/12/2013 om 07:16
bron van user

stemmen
1

nu hoeveel tekens u wilt geef waarden

 - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range   replacementString:(NSString *)string {
     NSUInteger newLength = [textField.text length] + [string length] - range.length;
     return (newLength > 25) ? NO : YES;
  }
antwoordde op 26/11/2013 om 12:30
bron van user

stemmen
1

Andere antwoorden niet het geval waar de gebruiker een lange reeks van klembord kunt plakken verwerken. Als ik plak een lange reeks moet gewoon worden afgekapt maar weergegeven. Gebruik dit in uw afgevaardigde:

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'

}
antwoordde op 04/04/2013 om 06:39
bron van user

stemmen
0

Swift 4.2+

Door de implementatie UITextFieldDelegatewerkwijze

...
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
}
antwoordde op 17/06/2019 om 11:46
bron van user

stemmen
0

Swift 4.2 en UITextFieldDelegate werkwijze

Dit werkt voor mij en beperkt het tekstveld tot een maximum ingang van 8 tekens lang zijn. Hopelijk NSRange zal uiteindelijk worden ingesteld met een bereik, maar voor nu ben ik blij om NSString gebruiken als het creëren van een bereik van NSRange betreft het omgaan met een ander optioneel.

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
}
antwoordde op 20/03/2019 om 00:40
bron van user

stemmen
0

Hoe zit het met deze eenvoudige aanpak. Het werkt prima voor mij.

extension UITextField {

    func  charactersLimit(to:Int) {

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

Dan:

someTextField.charactersLimit(to:16)
antwoordde op 04/09/2018 om 21:44
bron van user

stemmen
0

Gebruik de onderstaande extensie voor UITextFielden UITextViewtekenlimieten.

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

    extension UITextView:UITextViewDelegate {


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

            objc_setAssociatedObject(self, &kAssociationKeyMaxLength, 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
    }
}

U kunt de limiet hieronder.

voer image beschrijving hier

antwoordde op 26/07/2018 om 13:30
bron van user

stemmen
0

U kunt dit ook doen met behulp van NotificationCenter in Swift 4

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

            }         
        }
antwoordde op 06/06/2018 om 12:57
bron van user

stemmen
0

Ik geef een aanvullend antwoord op basis van @Frouo. Ik denk dat zijn antwoord is de mooiste manier. Vanwege het is een gemeenschappelijke regeling kunnen we hergebruiken.

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
    }

}
antwoordde op 06/02/2018 om 12:51
bron van user

stemmen
0

voor Swift 3.1 of hoger

ten eerste add protocol UITextFieldDelegate

net zoals:-

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

}

na dat maak je UITextField en stel afgevaardigde

Compleet 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 
    }
antwoordde op 28/06/2017 om 12:26
bron van user

stemmen
0

Ik wil toevoegen aan het antwoord van @sickp.

Er is een probleem in zijn Swiftcode die zich voordoet bij elke multibyte tekst (bijv emojis). NSRangeen Stringin Swiftniet compatibel zijn, dus het is frustrerend dat de gedelegeerde klasse ze combineert. De truc is gewoon om het om te zetten Stringvoorwerpen om NSStringde juiste oplossing, gebaseerd op wat @sickp schreef, is eigenlijk dit:

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
}
antwoordde op 07/04/2017 om 17:18
bron van user

stemmen
0

Als uw doel van het beperken van de tekst telling is om die tekst zal elders passen in een UILabel te garanderen, zou ik vermijd het gebruik van het aantal tekens. Het breekt met enkele emoji (proberen om een ​​dubbel emoji afkappen zal waarschijnlijk crashen van uw app). Het is ook een probleem met sommige talen, zoals Japans en Chinees, die een twee-staps-ingang proces waarbij een eenvoudige telling gewoon niet zal werken.

Ik bouwde een UITextField drop-in subklasse ( MPC_CharacterLimitedTextField op GitHub ). Je voedt dit de verwachte output label breedte en het zal omgaan met alle talen, emoji, en plakken kwesties. Het zal alleen zo veel full personages die past in het label, ongeacht het aantal tekens oogsten. Er is een demo in het project, zodat je het kan testen om te zien of het is wat je nodig hebt. Hoop dat het zal iedereen die had dezelfde problemen met uitvoerlengte dat ik helpen.

antwoordde op 30/11/2016 om 06:05
bron van user

stemmen
0

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

Hoop dat het helpt

antwoordde op 03/11/2015 om 23:54
bron van user

stemmen
0

Iets voorbij het beantwoorden van de oorspronkelijke vraag, en uit te breiden over het antwoord van Frouo's, hier zijn uitbreidingen van een String of witruimte en een maximale lengte trim, en om die String extensies gebruiken om een ​​UITextField trimmen tot een maximum lengte:

// 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()kunnen worden gebruikt in UITextFieldDelegate is textFieldDidEndEditing(_:)zodat een gebruiker kan invoeren of plakken langer dan acceptabel streng en inkorten versus net afsnijden van de ingang aan de maximumlengte. In dit te doen, zou ik ook instellen toegeschreven tekst stijlen om enig deel van de tekst die verder gaat dan de aanvaardbare lengte aan te geven (bijvoorbeeld,[NSBackgroundColorAttributeName : UIColor.redColor(), NSForegroundColorAttributeName : UIColor.whiteColor(), NSStrikethroughStyleAttributeName : NSNumber(int: 1)]

antwoordde op 01/05/2015 om 11:25
bron van user

stemmen
0

Dit beperkt het aantal tekens, maar er ook voor zorgen dat u kunt plakken in het veld tot de maximale limiet.

- (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
    }
}
antwoordde op 27/05/2014 om 21:10
bron van user

stemmen
0

kunnen we het bereik van tekstveld zoals dit in te stellen ..

-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range  replacementString:(NSString *)string
{
     int setrange = 20;
     return !([textField.text length]>setrange && [string length] > range.length);
}
antwoordde op 20/05/2014 om 11:51
bron van user

stemmen
0
(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;
}
antwoordde op 19/05/2014 om 15:48
bron van user

stemmen
0

Het probleem met een deel van het antwoord hierboven gegeven is, Zo heb ik een tekstveld en ik moet een limiet van 15 tekens ingang in te stellen, dan houdt het na het invoeren van de 15e Karakter. maar zij niet toestaan ​​om te verwijderen. Dat is de delete-knop ook niet werken. Zoals ik werd geconfronteerd met hetzelfde probleem. Kwam met de oplossing, hieronder gegeven. Werkt perfect voor mij

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

Ik heb een tekstveld, wiens tag ik heb ingesteld "6" en ik heb de max char limit = 30 beperkt; werkt prima in alle gevallen

antwoordde op 21/03/2014 om 15:36
bron van user

stemmen
-1
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
    if (textField.text.length >= 50) {
        return NO;
    }
    return YES;
}
antwoordde op 29/04/2015 om 07:02
bron van user

stemmen
-6

Ik vond dit snel en eenvoudig

- (IBAction)backgroundClick:(id)sender {
    if (mytext.length <= 7) {
        [mytext resignFirstResponder];
    } else {
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Too Big" 
                                                        message:@"Please Shorten Name"
                                                       delegate:nil 
                                              cancelButtonTitle:@"Cancel"
                                              otherButtonTitles:nil];
        [alert show];
        [alert release];
    }
}
antwoordde op 19/03/2010 om 21:54
bron van user

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more