Set the maximum character length of a UITextField
当我加载
虽然
Objective-C的
1 2 3 4 5 6 7 8 9 10 | - (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; } |
迅速
1 2 3 4 5 6 7 8 9 | 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 } |
在文本字段更改之前,UITextField会询问委托是否应更改指定的文本。此时文本字段没有改变,所以我们抓住它的当前长度和我们插入的字符串长度(通过粘贴复制的文本或使用键盘键入单个字符),减去范围长度。如果此值太长(在此示例中超过25个字符),则返回
在文本字段末尾键入单个字符时,
删除单个字符或剪切多个字符由
关于崩溃"撤消"错误的说明
正如评论中所提到的,
如果您粘贴到该字段,但验证实现阻止了粘贴,则粘贴操作仍会记录在应用程序的撤消缓冲区中。如果然后触发撤消(通过摇动设备并确认撤消),
幸运的是,你可以保护
swift 3.0,复制和粘贴工作正常。
1 2 3 4 5 6 7 8 | 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 } |
希望它对你有所帮助。
谢谢八月! (POST)
这是我最终使用的代码:
1 2 3 4 5 6 7 8 9 10 11 | #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;} } |
斯威夫特4
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | 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 } } |
编辑:内存泄漏问题已修复。
要完成8月份答案,可以实现所提议的函数(请参阅UITextField的委托)。
我没有测试domness代码,但是如果用户达到了限制,我不会卡住,并且它与替换较小或相等的新字符串兼容。
1 2 3 4 5 | -(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); } |
你不能直接这样做 -
1 | - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string |
通常,您有多个具有不同长度的输入字段。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | - (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 } } |
最好的方法是设置文本更改通知。在您的视图控制器方法的
1 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(limitTextField:) name:@"UITextFieldTextDidChangeNotification" object:myTextField]; |
然后在同一个类中添加:
1 2 3 4 5 6 | - (void)limitTextField:(NSNotification *)note { int limit = 20; if ([[myTextField stringValue] length] > limit) { [myTextField setStringValue:[[myTextField stringValue] substringToIndex:limit]]; } } |
然后将插座
1 | [[NSNotificationCenter defaultCenter] removeObserver:self name:@"UITextFieldTextDidChangeNotification" object:myTextField]; |
这应该足以解决问题(用你想要的限制替换4)。只需确保在IB中添加委托。
1 2 3 4 5 | - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string { NSString *newString = [textField.text stringByReplacingCharactersInRange:range withString:string]; return (newString.length<=4); } |
我创建了这个UITextFieldLimit子类:
- 支持多个文本字段
- 设置文本长度限制
- 粘贴预防
- 在文本字段内显示左侧字符的标签,在停止编辑时隐藏。
- 没有人物离开时动摇动画。
从此GitHub存储库中获取
https://github.com/JonathanGurebo/UITextFieldLimit
并开始测试!
标记您的故事板创建的UITextField并使用Identity Inspector将其链接到我的子类:
然后,您可以将其链接到IBOutlet并设置限制(默认值为10)。
您的ViewController.h文件应包含:(如果您不想修改设置,如限制)
1 2 3 4 5 | #import"UITextFieldLimit.h" /.../ @property (weak, nonatomic) IBOutlet UITextFieldLimit *textFieldLimit; // <--Your IBOutlet |
您的ViewController.m文件应
在ViewController.m文件中设置文本长度限制:
1 2 3 4 5 6 7 | - (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. } |
希望全班同学帮助你。祝好运!
我模拟了即将发生的实际字符串替换,以计算未来字符串的长度:
1 2 3 4 5 6 7 8 9 | - (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; } |
Swift 3版
// *****这不适用于Swift 2.x! // *****
首先创建一个新的Swift文件:TextFieldMaxLength.swift,
然后添加以下代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | 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 } } |
然后,当您选择任何TextField时,您将在Storyboard中看到一个新字段(Max Length)
如果您还有更多问题,请查看以下链接:http://www.globalnerdy.com/2016/05/18/ios-programming-trick-how-to-use-xcode-to-set-a-text-fields - 最大长度视觉工作室风格/
使用"界面"构建器,您可以在任何功能中链接并获取"编辑已更改"的事件。
现在你可以检查长度
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | - (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; } } |
以下代码类似于sickp的答案,但处理正确的复制粘贴操作。如果您尝试粘贴长度超过限制的文本,以下代码将截断文本以适应限制,而不是完全拒绝粘贴操作。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | - (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; } } |
在Swift中设置最大长度的通用解决方案。
通过IBInspectable,您可以在Xcode Attribute Inspector中添加新属性。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | 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 } } |
为了使它能够剪切和粘贴任何长度的字符串,我建议将函数更改为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | #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; } } |
swift 3.0
粘贴字符串超过字符限制时,此代码工作正常。
1 2 3 4 5 6 7 8 | 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 } |
谢谢你的投票。 :)
Swift 2.0 +
首先为此过程创建一个类。让我们称之为StringValidator.swift。
然后只需在其中粘贴以下代码即可。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | 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 } } |
现在保存班级......
用法..
现在转到你的viewController.swift类,并将你的textfield的出口作为..
1 2 | @IBOutlet weak var contactEntryTxtFld: UITextField! //First textfield @IBOutlet weak var contactEntryTxtFld2: UITextField! //Second textfield |
现在转到textfield的shouldChangeCharactersInRange方法并使用如下所示。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | 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 } } |
不要忘记设置文本字段的委托协议/方法。
让我解释一下......我正在使用我在另一个类中编写的字符串的简单扩展过程。现在我只是通过添加检查和最大值来从我需要它的另一个类调用这些扩展方法。
特征...
类型...
containsOnlyCharactersIn //仅接受字符。
containsCharactersIn //接受字符组合
doesNotContainsCharactersIn //不接受字符
希望这有助于....
谢谢..
使用以下扩展名设置
Swift 4.0
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | private var kAssociationKeyMaxLength: Int = 0 private var kAssociationKeyMaxLengthTextView: Int = 0 extension UITextField { @IBInspectable var maxLength: Int { get { if let length = objc_getAssociatedObject(self, &kAssociationKeyMaxLength) as? Int { return length } else { return Int.max } } set { objc_setAssociatedObject(self, &kAssociationKeyMaxLength, newValue, .OBJC_ASSOCIATION_RETAIN) addTarget(self, action: #selector(checkMaxLength), for: .editingChanged) } } @objc func checkMaxLength(textField: UITextField) { guard let prospectiveText = self.text, prospectiveText.count > maxLength else { return } let selection = selectedTextRange let indexEndOfText = prospectiveText.index(prospectiveText.startIndex, offsetBy: maxLength) let substring = prospectiveText[..<indexEndOfText] text = String(substring) selectedTextRange = selection } } extension UITextView:UITextViewDelegate { @IBInspectable var maxLength: Int { get { if let length = objc_getAssociatedObject(self, &kAssociationKeyMaxLengthTextView) as? Int { return length } else { return Int.max } } set { self.delegate = self objc_setAssociatedObject(self, &kAssociationKeyMaxLengthTextView, newValue, .OBJC_ASSOCIATION_RETAIN) } } public func textViewDidChange(_ textView: UITextView) { checkMaxLength(textField: self) } @objc func checkMaxLength(textField: UITextView) { guard let prospectiveText = self.text, prospectiveText.count > maxLength else { return } let selection = selectedTextRange let indexEndOfText = prospectiveText.index(prospectiveText.startIndex, offsetBy: maxLength) let substring = prospectiveText[..<indexEndOfText] text = String(substring) selectedTextRange = selection } } |
您可以在下面设置限制。
斯威夫特4
1 2 3 4 5 | 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 } |
我基于@Frouo给出了补充答案。我认为他的回答是最美好的方式。因为它是我们可以重复使用的通用控件。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | 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 } } |
这是在UITextField上处理最大长度的正确方法,它允许返回键退出作为第一响应者的文本字段,并在用户达到限制时让用户退格
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string { int MAX_LENGHT = 5; if([string isEqualToString:@" "]) { [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; } } |
对于Xamarin:
1 2 3 4 5 | YourTextField.ShouldChangeCharacters = delegate(UITextField textField, NSRange range, string replacementString) { return (range.Location + replacementString.Length) <= 4; // MaxLength == 4 }; |
Swift 4.2和UITextFieldDelegate方法
这对我有用,并限制文本字段的最大输入为8个字符。 希望NSRange最终会更改为Range但是现在我很乐意使用NSString,因为从NSRange创建一个Range涉及处理另一个可选项。
1 2 3 4 5 6 | func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { let text = textField.text ??"" let nsString = text as NSString let newText = nsString.replacingCharacters(in: range, with: string) return newText.count <= 8 } |
这个简单的方法怎么样? 它对我来说很好。
1 2 3 4 5 6 7 8 9 | extension UITextField { func charactersLimit(to:Int) { if (self.text!.count > to) { self.deleteBackward() } } } |
然后:
1 | someTextField.charactersLimit(to:16) |
您也可以使用Swift 4中的NotificationCenter执行此操作
1 2 3 4 5 6 7 8 9 10 11 12 | 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 } } |
其他答案不处理用户可以从剪贴板粘贴长字符串的情况。如果我粘贴一个长字符串,它应该被截断但显示。
在你的代表中使用它:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | static const NSUInteger maxNoOfCharacters = 5; -(IBAction)textdidChange:(UITextField * )textField { NSString * text = textField.text; if(text.length > maxNoOfCharacters) { text = [text substringWithRange:NSMakeRange(0, maxNoOfCharacters)]; textField.text = text; } // use 'text' } |
现在你想要多少个字符给出值
1 2 3 4 | - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string { NSUInteger newLength = [textField.text length] + [string length] - range.length; return (newLength > 25) ? NO : YES; } |
我已经实现了一个UITextField扩展来为它添加一个maxLength属性。
它基于Xcode 6 IBInspectables,因此您可以在"接口"构建器上设置maxLength限制。
这是实施:
UITextField+MaxLength.h
1 2 3 4 5 6 | #import <UIKit/UIKit.h> @interface UITextField_MaxLength : UITextField<UITextFieldDelegate> @property (nonatomic)IBInspectable int textMaxLength; @end |
UITextField+MaxLength.m
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | #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 |
如果限制文本计数的目的是确保文本适合其他地方的UILabel,我将避免使用字符计数。它与一些表情符号分解(试图截断双倍大小的表情符号可能会崩溃您的应用程序)。这也是日语和中文等语言的问题,它们有两步输入过程,简单的计数就行不通。
我构建了一个UITextField drop-in子类(github上的MPC_CharacterLimitedTextField)。您为它提供了预期的输出标签宽度,它将处理所有语言,表情符号和粘贴问题。无论字符数是多少,它都只会收集适合标签的多个完整字符。项目中有一个演示,所以你可以测试它,看看它是否是你需要的。希望它能帮助任何与输出长度问题相同的人。
把它归结为1行代码:)
将文本视图的委托设置为"self",然后在.h中添加
1 2 3 | -(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); } |
此代码用于键入新字符,删除字符,选择字符然后键入或删除,选择字符和剪切,粘贴,以及选择字符和粘贴。
完成!
或者,使用位操作编写此代码的另一种很酷的方法是
1 2 3 | -(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)); } |
当我使用数字键盘时,我在Swift中做了8个字符的限制。
1 2 3 | func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool { return !(textField.text?.characters.count == MAX_LENGTH && string !="") } |
我必须测试字符串!="以允许删除按钮在数字键盘上工作,否则它将不允许在文本字段达到其最大值后删除字符。
我已经开源了一个UITextField子类STATextField,它通过其
在此处使用此代码RESTRICTED_LENGTH是您要为textfield限制的长度。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string { if (textField == nameTF) { int limit = RESTRICTED_LENGTH - 1; return !([textField.text length]>limit && [string length] > range.length); } else { return YES; } return NO; } |
1 2 3 4 5 6 7 8 9 10 11 | (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; } |
我们可以像这样设置文本字段的范围。
1 2 3 4 5 | -(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string { int setrange = 20; return !([textField.text length]>setrange && [string length] > range.length); } |
这限制了字符数,但也确保您可以粘贴字段直到最大限制。
1 2 3 4 5 6 7 8 9 10 | - (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 } } |
我想补充@sickp给出的答案。
他的
1 2 3 4 5 6 7 8 9 10 | 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 } |
对于Swift 3.1或更高版本
首先添加协议
喜欢:-
1 2 3 4 5 6 | class PinCodeViewController: UIViewController, UITextFieldDelegate { ..... ..... ..... } |
之后,创建您的UITextField并设置委托
完成Exp: -
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | 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 } |
上面给出的一些答案的问题是,例如我有一个文本字段,我必须设置15个字符输入的限制,然后在输入第15个字符后停止。但他们不允许删除。那是删除按钮也不起作用。因为我面临同样的问题。推出解决方案,给定下面。适合我的作品
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | - (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; } } |
我有一个文本字段,其标签我设置为"6"
我限制了最大字符数限制= 30;
在每种情况下都能正常工作
稍微回答原始问题,并扩展Frouo的答案,这里是修剪一个空格字符串和最大长度的扩展,并利用这些字符串扩展将UITextField修剪为最大长度:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | // 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" |
适用于Swift 2.1+
1 2 3 4 5 6 7 8 9 10 | 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 } |
希望能帮助到你
Swift 4.2+
通过实现
视图控制器:
1 2 3 4 5 6 7 8 9 10 | class MyViewController: UIViewController { let MAX_LENGTH = 256 @IBOutlet weak var myTextField: UITextField! override viewDidLoad() { self.myTextField.delegate = self } } |
代表:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | extension MyViewController: UITextFieldDelegate { func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { let userText = textView.text ??"" var newText ="" if range.length > 0 { let txt = NSString(string: userText) if txt.length > 0 { newText = txt.replacingCharacters(in: range, with: text) } } else { newText = userText + text } return newText.count <= MAX_LENGTH } } |
1 2 3 4 5 6 | -(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string { if (textField.text.length >= 50) { return NO; } return YES; } |
我发现这很简单
1 2 3 4 5 6 7 8 9 10 11 12 13 | - (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]; } } |