UITextField
当我加载一个时,如何设置iPhone SDK上的最大字符数UIView
?
虽然UITextField
类没有max length属性,但通过设置文本字段delegate
并实现以下委托方法来获得此功能相对简单:
Objective-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; }
迅速
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个字符),则返回NO
以禁止更改.
当在文本字段的末尾键入单个字符时,range.location
将是当前字段的长度,并且range.length
将为0,因为我们不替换/删除任何内容.插入文本字段的中间只是意味着不同range.location
,粘贴多个字符只意味着其中string
包含多个字符.
删除单个字符或剪切多个字符由a指定,range
长度为非零,空字符串.替换只是一个非空字符串的范围删除.
正如评论中提到的那样,有一个错误UITextField
可能会导致崩溃.
如果粘贴到字段中,但验证实现阻止了粘贴,则粘贴操作仍会记录在应用程序的撤消缓冲区中.如果你随后触发撤消(通过摇动设备并确认撤消),UITextField
则会尝试用空字符串替换它认为粘贴的字符串.这会崩溃,因为它从未真正将字符串粘贴到自身.它将尝试替换不存在的字符串的一部分.
幸运的是,你可以保护UITextField
自己不会像这样自杀.您只需要确保它建议替换的范围确实存在于其当前字符串中.这是上面的初步健全检查.
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 }
希望它对你有所帮助.
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[..编辑:内存泄漏问题已修复.
我已编辑@Ixx,以解决您指出的问题和Swift 3带来的内存泄漏问题。
3> Domness..:谢谢八月!(发布)
这是我最终使用的代码:
#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;} }
遗憾的是,此解决方案无法阻止用户复制并粘贴到文本字段中,因此允许用户绕过限制.Sickpea的答案正确地应对了这种情况.
如果人们有if语句返回NO或YES?试试这个:return!(textField.text.length> = MAX_LENGTH && range.length == 0);
4> Jmini..:要完成8月份答案,可以实现所提议的函数(请参阅UITextField的委托).
我没有测试domness代码,但是如果用户达到了限制,我不会卡住它,并且它与一个新的字符串兼容,它取代了一个更小或相等的字符串.
-(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); }
5> August..:你不能直接这样做 -
UITextField
没有maxLength属性,但你可以设置UITextField's
委托,然后使用:- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
我同意,这是最好的前进方式,但它仍然是一个黑客.向Apple提交一个错误报告,您希望查看文本长度的属性.我对这一点也很感兴趣.
@avocade,这不是一个黑客:这是一个例子,你必须做你应该为你完成的基本框架代码.iOS SDK中有很多这样的例子.
6> Vincent..:通常,您有多个具有不同长度的输入字段.
- (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 } }
7> Martin Pilki..:最好的方法是设置文本更改通知.在您
-awakeFromNib
的视图控制器方法中,您需要:[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(limitTextField:) name:@"UITextFieldTextDidChangeNotification" object:myTextField];然后在同一个类中添加:
- (void)limitTextField:(NSNotification *)note { int limit = 20; if ([[myTextField stringValue] length] > limit) { [myTextField setStringValue:[[myTextField stringValue] substringToIndex:limit]]; } }然后将插座连接
myTextField
到您,UITextField
并且在达到限制后不会再添加任何字符.请务必将此添加到您的dealloc方法:[[NSNotificationCenter defaultCenter] removeObserver:self name:@"UITextFieldTextDidChangeNotification" object:myTextField];
8> Nishant..:这应该足以解决问题(用你想要的限制替换4).只需确保在IB中添加委托.
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string { NSString *newString = [textField.text stringByReplacingCharactersInRange:range withString:string]; return (newString.length<=4); }
9> Jonathan Gur..:我创建了这个 UITextFieldLimit子类:
支持多个文本字段
设置文本长度限制
粘贴预防
在文本字段内显示左侧字符的标签,在停止编辑时隐藏.
没有人物离开时动摇动画.
抓住
UITextFieldLimit.h
并UITextFieldLimit.m
从该GitHub的仓库:https://github.com/JonathanGurebo/UITextFieldLimit
并开始测试!
标记您的故事板创建的UITextField并使用Identity Inspector将其链接到我的子类:
然后,您可以将其链接到IBOutlet并设置限制(默认值为10).
您的ViewController.h文件应包含:(如果您不想修改设置,如限制)
#import "UITextFieldLimit.h" /.../ @property (weak, nonatomic) IBOutlet UITextFieldLimit *textFieldLimit; // <--Your IBOutlet
你的ViewController.m文件应该
@synthesize textFieldLimit
.
在ViewController.m文件中设置文本长度限制:
- (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. }希望全班同学帮助你.祝好运!
10> samvermette..:我模拟了即将发生的实际字符串替换,以计算未来字符串的长度:
- (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; }
11> Gilad Brunfm..:Swift 3版本//*****这不适用于Swift 2.x!//*****
首先创建一个新的Swift文件:TextFieldMaxLength.swift,然后添加以下代码:
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 -最大长度视觉工作室风格/
12> 小智..:使用"界面"构建器,您可以在任何功能中链接并获取"编辑已更改"的事件.现在你可以检查长度
- (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; } }
13> 小智..:以下代码类似于sickp的答案,但处理正确的复制粘贴操作.如果您尝试粘贴长度超过限制的文本,以下代码将截断文本以适应限制,而不是完全拒绝粘贴操作.
- (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; } }
14> Hiren..:没有通用的解决方案在斯威夫特设置最大长度.通过IBInspectable,您可以在Xcode Attribute Inspector中添加新属性.
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(prospectiveText.startIndex ..< prospectiveText.startIndex.advancedBy(maxLength)) ) selectedTextRange = selection } }
15> Påhl Melin..:为了使它能够剪切和粘贴任何长度的字符串,我建议将函数更改为:
#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; } }