当我尝试使用 如何使用迅速设置可以输入到 UITextField 中的最大字符数?时,我发现如果我使用所有10个字符,我就不能删除这个字符。
我唯一能做的就是取消操作(一起删除所有字符)。
是否有人知道如何不阻塞键盘(以便我不能添加其他字母/符号/数字,但我可以使用退格) ?
您需要检查现有字符串加上输入是否大于10。
func textField(textField: UITextField!,shouldChangeCharactersInRange range: NSRange, replacementString string: String!) -> Bool { NSUInteger newLength = textField.text.length + string.length - range.length; return !(newLength > 10) }
使用 Swift 5和 iOS 12,尝试以下 textField(_:shouldChangeCharactersIn:replacementString:)方法的实现,这是 UITextFieldDelegate协议的一部分:
textField(_:shouldChangeCharactersIn:replacementString:)
UITextFieldDelegate
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<String.Index>
textField
smartInsertDeleteType
UITextSmartInsertDeleteType.no
下面的完整示例代码展示了如何在 UIViewController中实现 textField(_:shouldChangeCharactersIn:replacementString:):
UIViewController
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 } }
我是这样做的:
func checkMaxLength(textField: UITextField!, maxLength: Int) { if (countElements(textField.text!) > maxLength) { textField.deleteBackward() } }
密码对我有用。但我是做故事板的。在 Storyboard 中,我为 剪辑变了上的视图控制器中的文本字段添加了一个操作。
我发布了一个解决方案使用 IBInspectable,所以你可以改变最大长度值在 Interface Builder 或程序。看看这里
IBInspectable
注意本文中提到的 UITextField 的撤消错误: 设置 UITextField 的最大字符长度
这就是你迅速解决问题的方法
if(range.length + range.location > count(textField.text)) { return false; }
从@Martin 的回答中添加更多细节
// 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() } }
func checkMaxLength(textField: UITextField!, maxLength: Int) { if (textField.text!.characters.count > maxLength) { textField.deleteBackward() } }
IOS 9的一个小改动
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 }
我一直在我的一个应用程序中使用这个协议/扩展,它的可读性更好一些。我喜欢它识别退格并明确告诉你什么时候一个字符是退格。
有些事情需要考虑:
1.无论是什么实现了这个协议扩展,都需要指定一个字符限制。 这通常是 ViewController,但是您可以将字符限制实现为一个计算属性,并返回其他内容,例如在您的某个模型上的字符限制。
2.您需要在文本字段的 should dChangePersontersInRange 委托方法内调用此方法。否则,您将无法通过返回 false 等来阻止文本输入。
3.您可能希望允许退格字符通过。这就是为什么我添加了额外的函数来检测后退空间。您的 should dChangeProperties 方法可以检查这一点,并在早期返回“ true”,因此始终允许使用退格。
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 上有限字符框架
Swift 3
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 }
因为委托是一对一的关系,我可能会因为其他原因而在其他地方使用它,所以我喜欢限制 textfield 长度,在它们的设置中添加以下代码:
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) }
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 }
如果你想覆盖最后一个字母:
let maxLength = 10 func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { if range.location > maxLength - 1 { textField.text?.removeLast() } return true }
在 Swift 4 中
文本字段限制为10个字符并允许删除(退格)
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 }
你可以使用迅速5或迅速4像 图像看起来像下面这样
在视图 ViewController 中添加代码
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; } }
You can download Full Source form GitHub: https://github.com/enamul95/TextFieldMaxLen
您可以扩展 UITextField 并添加一个 @IBInspectable对象来处理它:
@IBInspectable
SWIFT 5
import UIKit private var __maxLengths = [UITextField: Int]() extension UITextField { @IBInspectable var maxLength: Int { get { guard let l = __maxLengths[self] else { return 150 // (global default-limit. or just, Int.max) } return l } set { __maxLengths[self] = newValue addTarget(self, action: #selector(fix), for: .editingChanged) } } @objc func fix(textField: UITextField) { if let t = textField.text { textField.text = String(t.prefix(maxLength)) } } }
然后在属性检查器上定义它
参见 Swift 4原创答案
我用这个;
限制3个字符
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { if let txt = textField.text { let currentText = txt + string if currentText.count > 3 { return false } return true } return true }
Swift 5
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { let MAX_LENGTH = 4 let updatedString = (textField.text! as NSString).replacingCharacters(in: range, with: string) return updatedString.count <= MAX_LENGTH }
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { if textField == myTextFieldName { if range.location > 10 { return false } } return true }
或者
func textFieldDidChangeSelection(_ textField: UITextField) { myTextFieldName.text = String(myTextFieldName.text!.prefix(10)) }
这是我的简单答案,在 Swift 5.0中使用 iOS 14 + 和 Xcode 12 + ..。
在 viewDidLoad()中添加以下选择器:
viewDidLoad()
override func viewDidLoad() { // Add a target for myTextField, pointing to .editingDidChange myTextField.addTarget(self, action: #selector(myTextFieldDidChange(_:)), for: .editingChanged) }
在类的某个地方,您还可以添加一个可选的字符限制:
// Add an optional character limit let characterLimit = 100
然后在后面的课上,只需要添加这个函数:
@objc func myTextFieldDidChange(_ textField: UITextField) { textField.text = String(textField.text!.prefix(self.characterLimit)) }
这将限制您的字符要么当您键入,或者当您复制 + 粘贴文本到文本字段。