Hoe kan ik het maximum aantal tekens in een UITextFieldop de iPhone SDK wanneer ik laden een UIView?
De maximale tekenlengte een UITextField
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.
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;}
}
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.
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);
}
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
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
}
}
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];
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:

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!
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);
}
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 /
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;
}
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;
}
}
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;
}
}
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;
}
}
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.
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
}
}
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. :)
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...
- Het zal maximum van een bepaald tekstveld in te stellen.
- 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 ..
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;
}
}
Voor Xamarin:
YourTextField.ShouldChangeCharacters =
delegate(UITextField textField, NSRange range, string replacementString)
{
return (range.Location + replacementString.Length) <= 4; // MaxLength == 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
}
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.
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;
}
Ik heb open source een UITextField subklasse STATextField , die deze functionaliteit (en nog veel meer) met zijn biedt maxCharacterLengtheigendom.
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
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));
}
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;
}
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'
}
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
}
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
}
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)
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.
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
}
}
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
}
}
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
}
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
}
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.
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
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)]
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
}
}
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);
}
(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;
}
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
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
if (textField.text.length >= 50) {
return NO;
}
return YES;
}
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];
}
}















