仅从其中文本的末尾启用编辑 TextField

Posted

技术标签:

【中文标题】仅从其中文本的末尾启用编辑 TextField【英文标题】:Enable editing TextField only from the end of the text inside it 【发布时间】:2020-12-18 16:00:39 【问题描述】:

我正在为电话号码创建一个 TextField。 但是我有一些麻烦:我需要防止用户从任何地方编辑它,而不是字符串的末尾。

我尝试使用“Touch up Inside”重置插入符号,但它似乎对 TextField 禁用。

有没有办法限制插入符号的可能位置?

问题是它破坏了我的代码,它格式化了电话号码。如果您有任何其他好的方法来格式化它而不会出现这个问题(我需要字符串看起来完全像这样:+7 (123) 456-78-90,而不是任何其他方式),我会感谢您的帮助。

private static var prev_phone: String = ""
@IBAction func phoneFieldTextChanged(_ sender: Any)
    if let phone = phone_field.text
        if(phone.count <= 4)
            phone_field.text = "+7 ("
        
        else
            if phone.count > RegistrationViewController.prev_phone.count
                if(phone.count == 7)
                    phone_field.text! += ") "
                
                if(phone.count == 12)
                    phone_field.text! += "-"
                
                if(phone.count == 15)
                    phone_field.text! += "-"
                
                if(phone.count > 18)
                    phone_field.text = String(phone.prefix(18))
                
            
            if phone.count < RegistrationViewController.prev_phone.count
                if(phone.count == 8)
                    phone_field.text! = String(phone.prefix(6))
                
                if(phone.count == 12)
                    phone_field.text! = String(phone.prefix(11))
                
                if(phone.count == 15)
                    phone_field.text! = String(phone.prefix(14))
                
                if(phone.count > 18)
                    phone_field.text = String(phone.prefix(18))
                
            
        
    
    else
        phone_field.text = "+7 ("
    
    RegistrationViewController.prev_phone = phone_field.text!

【问题讨论】:

【参考方案1】:

将此类分配给您的文本字段,以防止用户从任何地方对其进行编辑。

class RestrictionTextField: UITextField 

    override func closestPosition(to point: CGPoint) -> UITextPosition? 
        let beginning = self.beginningOfDocument
        let end = self.position(from: beginning, offset: self.text?.count ?? 0)
        return end
    
    
    override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool 
        if action == #selector(UIResponderStandardEditActions.copy(_:)) || action == #selector(UIResponderStandardEditActions.select(_:)) || action == #selector(UIResponderStandardEditActions.cut(_:)) || action == #selector(UIResponderStandardEditActions.paste(_:)) || action == #selector(UIResponderStandardEditActions.selectAll(_:))
            return false
        
        else 
            return super.canPerformAction(action, withSender: sender)
        
    

为了您的文本字段,您可以使用这个简单的解决方案。

let kPhonePattern = "+# (###) ###-##-##"
let kPhonePatternReplaceChar: Character = "#"

extension String 
    var digits: String 
        return String(filter(("0"..."9").contains))
    
    
    func applyPatternOnNumbers(pattern: String = kPhonePattern, replacmentCharacter: Character = kPhonePatternReplaceChar) -> String 
        var pureNumber = self.replacingOccurrences( of: "[^0-9]", with: "", options: .regularExpression)
        for index in 0 ..< pattern.count 
            guard index < pureNumber.count else  return pureNumber 
            let stringIndex = String.Index(encodedOffset: index)
            let patternCharacter = pattern[stringIndex]
            guard patternCharacter != replacmentCharacter else  continue 
            pureNumber.insert(patternCharacter, at: stringIndex)
        
        return pureNumber
    

用法:

@IBAction func phoneFieldTextChanged(_ sender: UITextField)
    sender.text = sender.text?.applyPatternOnNumbers()

【讨论】:

哇,这两种解决方案都真正做到了他们想要做的事情。非常感谢您花时间回答这样愚蠢的问题) 不需要字符串初始化程序。 filterapplied 在字符串上返回一个字符串。 var digits: String filter(("0"..."9").contains) 。顺便说一句,您为什么添加该属性但没有使用它? var pureNumber = digits @LeoDabus 我添加了,如果您需要从文本字段(带模式)中获取数字,那么它很有用。它只返回数字。并感谢过滤器更正。【参考方案2】:

在这种情况下,为什么要使用 UITextField ? 例如,您可以创建一个自己制作的自定义键盘,只有数字和删除按钮。 用户只能输入一个数字或删除它。将输入的数字添加到格式化字符串由您决定。

【讨论】:

以上是关于仅从其中文本的末尾启用编辑 TextField的主要内容,如果未能解决你的问题,请参考以下文章

在Android中的编辑文本中从末尾键入文本[重复]

SQL查询/函数仅从末尾删除字母

仅从已更改的文本输入中收集值

textview - 开始编辑时将光标放在文本末尾

将不可编辑的文本附加到输入的末尾?

有没有办法在编辑时将 TextField 的光标移动到文本的末尾?- SwiftUI