最大长度UITextField

145

当我尝试使用如何使用Swift设置可以输入到UITextField中的最大字符数?时,我发现如果我使用了全部10个字符,我无法擦除字符。

我唯一能做的就是取消操作(一次性删除所有字符)。

有人知道如何不阻止键盘(这样我就可以使用退格键,但不能添加其他字母/符号/数字)吗?

20个回答

5

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
    }

4

我发布了一个使用 IBInspectable 的解决方案,这样你就可以在界面构建器中或编程中更改最大长度值。 点击此处查看


4
您可以在 Swift 5 或 Swift 4 中使用以下方式实现: 图像显示如下: enter image description here
  1. Add textField in View Controller
  2. Connect to text to ViewController
  3. add the code in view 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;
       }
    }
    
你可以从GitHub下载完整源代码:https://github.com/enamul95/TextFieldMaxLen

2

由于委托是一对一的关系,而且我可能希望出于其他原因在其他地方使用它,因此我喜欢在设置文本字段时添加以下代码来限制文本字段长度:

    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
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
我喜欢Toast UIView扩展 :) - Regis St-Gelais

1

注意此帖中提到的UITextField撤销错误:设置UITextField的最大字符长度

以下是您在Swift中修复它的方法。

if(range.length + range.location > count(textField.text)) {
        return false;
}

如果您想支持表情符号等,请使用以下代码:if (range.length + range.location > count(textField.text.utf16)){ return false; } - AlexD

1
我正在使用这个;
限制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
    }

1
I have been using this protocol/extension in one of my apps, and it's a little more readable. I like how it recognizes backspaces and explicitly tells you when a character is a backspace.
Some things to consider:
1.实现此协议扩展的任何内容都需要指定字符限制。通常会是您的ViewController,但您可以将字符限制实现为计算属性并返回其他内容,例如模型中的字符限制。
2.您需要在文本字段的shouldChangeCharactersInRange委托方法内调用此方法。否则,您将无法通过返回false等来阻止文本输入。
3.您可能希望允许退格字符通过。这就是我添加额外函数以检测退格的原因。您的shouldChangeCharacters方法可以检查这一点并尽早返回“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上的CharacterLimited框架


-1

这是我的简单答案,使用iOS 14+和Xcode 12+的Swift 5.0...

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))
}

这将限制您输入字符的数量,无论是在您键入时还是将文本复制粘贴到文本字段中。


-3
你需要检查现有字符串加上输入是否大于10。
   func textField(textField: UITextField!,shouldChangeCharactersInRange range: NSRange,    replacementString string: String!) -> Bool {
      NSUInteger newLength = textField.text.length + string.length - range.length;
      return !(newLength > 10)
   }

5
你的代码有误。1. 在Swift中,你必须使用let或var声明常量或变量(而不是NSUInteger)。2. textField.text和string都是String类型。在Swift中,Length不是String的属性或方法。 - Imanou Petit

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接