根据输入的字符限制文本字段的长度?

Posted

技术标签:

【中文标题】根据输入的字符限制文本字段的长度?【英文标题】:Limiting textField length depending on what characters are entered into it? 【发布时间】:2020-12-11 09:25:25 【问题描述】:

我有一个将长度限制为 3 的文本字段函数。这两个文本字段之一允许使用减号“-”。

如果我用数字键盘输入数字,它们会停在 3 个字符处。 如果我在后面键入一个带有数字的“-”,它们会停在 3 个字符处。

但是,

如果我只输入“-”,它们会持续的时间比我愿意承认的要长。

那么,如果我组合字符集以包括十进制数字和任何减号的设置----这是否允许我将文本字段限制为“单个”减号和最多 3 个数字?

【问题讨论】:

正在恢复。您是否尝试创建一个整数字段并希望将其输入限制在 -999 到 999 之间? 是的,那很好。我忽略了包括在内。只有一个文本字段允许减号。所以它只能(正确地)从 0 到 999。第二个字段允许减号,并且可以有效地给出 -999 到 999。它们只是整数的美元。在这种情况下,他们去的参考不处理小数。在我的第二个示例中,我应该改进:如果我输入“- 2 3 4 5”,它只会产生“-23”---三个字符。 【参考方案1】:

对于您的未签名文本字段,您可以使用此post 中显示的相同方法。因为您还需要进行一些更改以允许负输入。首先添加一个工具栏以允许用户切换正/负输入并使用范围而不是最大值。您无需检查用户输入的位数,只需确保输入的值包含在该范围内即可。要允许用户使用返回键完成对字段的编辑,您可以将该字段设为其委托并实现 textFieldShouldReturn 方法。最后但并非最不重要的一点是,在过滤数字时,请确保不要删除存在的减号前缀:


您的 SignedIntegerField 应如下所示:

import UIKit

class SignedIntegerField: UITextField, UITextFieldDelegate 
    var value: Int  string.digits.integer ?? 0 
    var range = -999...999
    private var lastValue: Int = 0
    override func willMove(toSuperview newSuperview: UIView?) 
        precondition(range ~= 0)
        
        delegate = self
        
        addToolbar()
        
        addTarget(self, action: #selector(editindDidEnd), for: .editingDidEnd)
        addTarget(self, action: #selector(editingChanged), for: .editingChanged)
        keyboardType = .numberPad
        textAlignment = .right
        sendActions(for: .editingChanged)
    
    
    func addToolbar() 
        let toolbar = UIToolbar()
        toolbar.sizeToFit()
        toolbar.barStyle = .default
        toolbar.items = [
            .init(title: "+/-",
                  style: .plain,
                  target: self,
                  action: #selector(minusAction)),
            .init(barButtonSystemItem: .flexibleSpace,
                  target: self,
                  action: nil),
            .init(title: "Clear",
                  style: .plain,
                  target: self,
                  action: #selector(clearAction)),
            .init(barButtonSystemItem: .flexibleSpace,
                  target: self, action: nil),
            .init(title: "Done",
                  style: .plain,
                  target: self,
                  action: #selector(doneAction))]
        
        inputAccessoryView = toolbar
    

    @objc func minusAction() 
        if text!.hasPrefix("-") 
            text!.removeFirst()
         else 
            text!.insert("-", at: text!.startIndex)
        
    
    
    @objc func clearAction()  text = "0" 
    @objc func doneAction() 
        if text == "-"  text = "0" 
        resignFirstResponder()
    

    override func deleteBackward() 
        text!.remove(at: text!.index(before: text!.endIndex))
        sendActions(for: .editingChanged)
    
    
    func textFieldShouldReturn(_ textField: UITextField) -> Bool 
        resignFirstResponder()
        return true
    
    @objc func editingChanged() 
        guard range ~= value else 
            text = Formatter.decimal.string(for: lastValue)
            return
        
        text = Formatter.decimal.string(for: value)
        print("Value:", value)
        lastValue = value
    
    @objc func editindDidEnd() 
        if text == "-"  text = "0" 
    


fileprivate extension UITextField 
    var string: String  text ?? "" 


fileprivate extension Formatter 
    static let decimal = NumberFormatter(numberStyle: .decimal)


fileprivate extension NumberFormatter 
    convenience init(numberStyle: Style) 
        self.init()
        self.numberStyle = numberStyle
    


fileprivate extension StringProtocol where Self: RangeReplaceableCollection 
    var digits: Self 
        first == "-" ?
            "-" + dropFirst().filter("0123456789".contains) :
            filter("0123456789".contains)
    
    var integer: Int?  Int(self) 

sample project

【讨论】:

【参考方案2】:

感谢所有这些!

我已经制作了一个工具栏,不想改变我的工作。

因此,我的文本字段受到范围的限制,具体取决于它所在的字段。

无符号的长度限制为 3。 签名的长度为 4 --- 仅当有“-”时。

它(再次)不是“最快的”,但我让它发挥了作用:

 var maxLength = 3   //checks to allow 3 digits in per1k and 4 digits in fecocollector
        if (textField == fecoCollector) && fecoCollector.text!.contains("-") 
             maxLength = 4
         else 
        
            maxLength = 3
        

我在工具栏上的按钮(我制作的一个否定按钮)将其作为选择器运行...最后调用主数学函数。

 @objc func preloadTheMinus() 
        

        let char: Character = "-" //something to compare against
        let fecoCollectorFilter = fecoCollector.text!
      
        
        minusCount = fecoCollectorFilter.filter  $0 == char .count //count the -'s
        print("fecoCollector has \(minusCount) minus in it")

        if fecoCollector.text!.hasPrefix("-") 
            fecoCollector.text!.removeFirst()
                     else 
            fecoCollector.text!.insert("-", at: fecoCollector.text!.startIndex)
                    
                
       doTheRemainingMath()
    

【讨论】:

以上是关于根据输入的字符限制文本字段的长度?的主要内容,如果未能解决你的问题,请参考以下文章

SQLServer的字段能存储的长度远远达不到该字段的数据类型限制的长度

什么是服务现在 SNOW 输入中的字符限制和受限字符

限制文本输入字段中的字符集

如何根据 TextField 的可见大小限制 UITextField 的输入文本量?

限制表单输入文本字段中允许的字符数

如何限制文本框输入长度