Max length UITextField
当我尝试过如何使用swift设置可以输入到UITextField中的最大字符数时,我看到如果我全部使用10个字符,我也无法擦除该字符。
我唯一能做的就是取消操作(一起删除所有字符)。
有谁知道如何不阻塞键盘(这样我就不能添加其他字母/符号/数字,但是我可以使用退格键)?
对于Swift 5和iOS 12,请尝试以下
1 2 3 4 5 6 7 8 9 | func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { guard let textFieldText = textField.text, let rangeOfTextToReplace = Range(range, in: textFieldText) else { return false } let substringToReplace = textFieldText[rangeOfTextToReplace] let count = textFieldText.count - substringToReplace.count + string.count return count <= 10 } |
-
该代码最重要的部分是从
range (NSRange )到rangeOfTextToReplace (Range )的转换。请参阅此视频教程,以了解为何此转换很重要。 -
为了使此代码正常工作,还应该将
textField 的smartInsertDeleteType 值设置为UITextSmartInsertDeleteType.no 。这将防止在执行粘贴操作时可能会插入(多余的)多余空间。
以下完整的示例代码显示了如何在
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | import UIKit class ViewController: UIViewController, UITextFieldDelegate { @IBOutlet var textField: UITextField! // Link this to a UITextField in Storyboard override func viewDidLoad() { super.viewDidLoad() textField.smartInsertDeleteType = UITextSmartInsertDeleteType.no textField.delegate = self } func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { guard let textFieldText = textField.text, let rangeOfTextToReplace = Range(range, in: textFieldText) else { return false } let substringToReplace = textFieldText[rangeOfTextToReplace] let count = textFieldText.count - substringToReplace.count + string.count return count <= 10 } } |
我这样做是这样的:
1 2 3 4 5 | func checkMaxLength(textField: UITextField!, maxLength: Int) { if (countElements(textField.text!) > maxLength) { textField.deleteBackward() } } |
该代码对我有用。但是我使用情节提要。在情节提要中,我在编辑更改时为视图控制器中的文本字段添加了操作。
Swift 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 } |
添加来自@Martin答案的更多详细信息
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | // linked your button here @IBAction func mobileTFChanged(sender: AnyObject) { checkMaxLength(sender as! UITextField, maxLength: 10) } // linked your button here @IBAction func citizenTFChanged(sender: AnyObject) { checkMaxLength(sender as! UITextField, maxLength: 13) } func checkMaxLength(textField: UITextField!, maxLength: Int) { // swift 1.0 //if (count(textField.text!) > maxLength) { // textField.deleteBackward() //} // swift 2.0 if (textField.text!.characters.count > maxLength) { textField.deleteBackward() } } |
在Swift 4中
文本字段最多10个字符,并允许删除(退格)
1 2 3 4 5 6 7 8 9 10 11 | func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { if textField == userNameFTF{ let char = string.cString(using: String.Encoding.utf8) let isBackSpace = strcmp(char,"\\b") if isBackSpace == -92 { return true } return textField.text!.count <= 9 } return true } |
1 2 3 4 5 | func checkMaxLength(textField: UITextField!, maxLength: Int) { if (textField.text!.characters.count > maxLength) { textField.deleteBackward() } } |
IOS 9的一个小改动
迅捷3
1 2 3 4 5 6 | func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { let nsString = NSString(string: textField.text!) let newText = nsString.replacingCharacters(in: range, with: string) return newText.characters.count <= limitCount } |
如果要覆盖最后一个字母:
1 2 3 4 5 6 7 8 9 10 | let maxLength = 10 func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { if range.location > maxLength - 1 { textField.text?.removeLast() } return true } |
我使用
由于委托是一对一关系,由于其他原因,我可能想在其他地方使用它,因此我想限制文本字段的长度,在其设置中添加以下代码:
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 | required init(coder aDecoder: NSCoder) { super.init(coder: aDecoder)! setup() } required override init(frame: CGRect) { super.init(frame: frame) setup() } func setup() { // your setup... setMaxLength() } let maxLength = 10 private func setMaxLength() { addTarget(self, action: #selector(textfieldChanged(_:)), for: UIControlEvents.editingChanged) } @objc private func textfieldChanged(_ textField: UITextField) { guard let text = text else { return } let trimmed = text.characters.prefix(maxLength) self.text = String(trimmed) } |
我一直在我的一个应用程序中使用此协议/扩展名,它更具可读性。我喜欢它如何识别退格键,并明确告诉您何时字符是退格键。
要考虑的一些事情:
1.无论采用哪种协议扩展,都需要指定字符数限制。通常,这将是您的ViewController,但是您可以将字符限制实现为计算属性,并返回其他内容,例如,其中一个模型的字符限制。
2.您将需要在文本字段的shouldChangeCharactersInRange委托方法内调用此方法。否则,您将无法通过返回false等来阻止文本输入。
3.您可能希望允许使用退格字符。这就是为什么我添加了额外的功能来检测退格键的原因。您的shouldChangeCharacters方法可以进行检查并尽早返回" true",因此您始终允许使用退格键。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | protocol TextEntryCharacterLimited{ var characterLimit:Int { get } } extension TextEntryCharacterLimited{ func charactersInTextField(textField:UITextField, willNotExceedCharacterLimitWithReplacementString string:String, range:NSRange) -> Bool{ let startingLength = textField.text?.characters.count ?? 0 let lengthToAdd = string.characters.count let lengthToReplace = range.length let newLength = startingLength + lengthToAdd - lengthToReplace return newLength <= characterLimit } func stringIsBackspaceWith(string:String, inRange range:NSRange) -> Bool{ if range.length == 1 && string.characters.count == 0 { return true } return false } } |
如果您有兴趣,我可以在Github存储库中采取一些这种字符限制行为并将其放入iOS框架。您可以实施一种协议来获得类似Twitter的字符数限制显示,以向您显示超出字符数限制的距离。
Github上的CharacterLimited框架
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | Here is my version of code. Hope it helps! func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool { let invalidCharacters = NSCharacterSet(charactersInString:"0123456789").invertedSet if let range = string.rangeOfCharacterFromSet(invalidCharacters, options: nil, range:Range<String.Index>(start: string.startIndex, end: string.endIndex)) { return false } if (count(textField.text) > 10 && range.length == 0) { self.view.makeToast(message:"Amount entry is limited to ten digits", duration: 0.5, position: HRToastPositionCenter) return false } else { } return true } |
谨防本文中提到的UITextField的撤消错误:设置UITextField的最大字符长度
这是您迅速解决的方法
1 2 3 | if(range.length + range.location > count(textField.text)) { return false; } |
您可以在swift 5或swift 4中使用类似波纹管的图像
在ViewController中添加代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | class ViewController: UIViewController , UITextFieldDelegate { @IBOutlet weak var txtName: UITextField! var maxLen:Int = 8; override func viewDidLoad() { super.viewDidLoad() txtName.delegate = self } func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { if(textField == txtName){ let currentText = textField.text! + string return currentText.count <= maxLen } return true; } } |
您可以从GitHub下载完整源代码表单:https://github.com/enamul95/TextFieldMaxLen
您需要检查现有字符串加上输入是否大于10。
1 2 3 4 | func textField(textField: UITextField!,shouldChangeCharactersInRange range: NSRange, replacementString string: String!) -> Bool { NSUInteger newLength = textField.text.length + string.length - range.length; return !(newLength > 10) } |