【问题标题】:While entering text in UITextField placeholder should disappear one letter at at time在 UITextField 占位符中输入文本时,应一次消失一个字母
【发布时间】:2017-06-15 18:19:18
【问题描述】:

我创建了一个UITextfield,我想在其中添加 4 位密码,但是一旦我输入第一个数字,整个占位符就会消失。如何在输入下一个密码字母时将下三个占位符字母保留在 UITextfield 中。

这是我的截图:

【问题讨论】:

    标签: ios swift uitextfield placeholder


    【解决方案1】:

    我想试试 SeanLintern88 的解决方案,因为它听起来有点挑战。在文本字段的下划线之间应该有空格的情况下。

    textField.text = "_ _ _ _"
    

    这是我自带的解决方案,虽然写起来很有趣,但我不建议在实际项目中使用。最好尝试 4 个单独的文本字段方法:)

    extension ViewController: UITextFieldDelegate {
    
        func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    
            guard let text = textField.text else { return false }
    
            var location = range.location
    
            //is deleting
            if string == "" {
    
                guard let indexToReplace = text.index(text.startIndex, offsetBy: location, limitedBy: text.endIndex) else {
                    return false
                }
    
                let isCharDeleted = location % 2 == 0
                //place " " or "_" depending on the position that was deleted
                let stringToReplaceWith = isCharDeleted ? "_" : " "
                let charachter = stringToReplaceWith[stringToReplaceWith.startIndex]
                textField.text?.remove(at: indexToReplace)
                textField.text?.insert(charachter, at: indexToReplace)
    
                var newCursorPositionOffset = location
    
                //deletetion occured on space " "
                if !isCharDeleted {
    
                    guard let previousIndex = text.index(text.startIndex, offsetBy: location-1, limitedBy: text.endIndex) else {
                        return false
                    }
                    //delete the previous charachter
                    textField.text?.remove(at: previousIndex)
                    let dash = "_"
                    let char = dash[dash.startIndex]
    
                    textField.text?.insert(char, at: previousIndex)
    
                    //correct cursor position
                    newCursorPositionOffset -= 1
                }
    
                //move cursor position
                let newPosition = textField.position(from: textField.beginningOfDocument, offset: newCursorPositionOffset)
                textField.selectedTextRange = textField.textRange(from: newPosition!, to: newPosition!)
    
                return false
            }
    
            //is typing
            if range.location + 1 <= text.characters.count,
                let end = text.index(text.startIndex, offsetBy: location+1, limitedBy: text.endIndex),
                let start = text.index(text.startIndex, offsetBy: location, limitedBy: text.endIndex) {
                textField.text = textField.text?.replacingOccurrences(of: "_", with: string, options: .caseInsensitive, range: Range(uncheckedBounds: (lower: start, upper: end)))
    
                //correct the cursor position if placed on " " index
                if range.location % 2 != 0 {
                    location -= 1
                }
            }
    
            //skip " " and move cursor to the next "_"
            if location+2 < text.characters.count {
                let newPosition = textField.position(from: textField.beginningOfDocument, offset: location+2)
                textField.selectedTextRange = textField.textRange(from: newPosition!, to: newPosition!)
    
            }
    
            return false
        }
    
        func textFieldDidBeginEditing(_ textField: UITextField) {
            let newPosition = textField.beginningOfDocument
            textField.selectedTextRange = textField.textRange(from: newPosition, to: newPosition)
    
    
        }
    }
    

    PS:也许可以通过更好地选择字符串操作的函数来缩短它,但仍然是一个相当不友好的解决方案。

    结论:不要在家里这样做:D

    【讨论】:

    • 感谢您的解决方案。它确实有效,但它太长了。我能把它缩短一点吗?
    【解决方案2】:

    不使用placeHolder,只需覆盖shouldChangeCharactersInRange 方法并将字符附加到字符串,直到字符串长度为4 个字符,如果您希望_ 看起来与点。

    【讨论】:

    • 尝试将占位符替换为“textField.text”。但它不起作用。我想用来自键盘的文本替换那些 4 '_'。有可能吗?
    • 我认为最好使用 4 个文本字段制作自定义解决方案
    • 多个文本字段在某些方面可能更容易,但不是必需的。您需要做的就是跟踪密码的属性字符串,然后替换输入的字符。
    【解决方案3】:

    斯威夫特 4

    这是@Denislava Shentova 答案的修改版本,我相信它可以简化为更少的代码行、修复问题并使代码更具可读性。

    未完全测试

    import UIKit
    
    class YourClass: UIViewController {
    
        //It is also a good idea to deny users the ability to paste into this textField.
    
        //set up textField
        let textField : UITextField = {
            let textField = UITextField()
            // These are 'long dashes' you can replace them with whatever you would like.
            // These look best IMO.
            textField.text = "——————" //No spaces needed!
            textField.textColor = .black
            textField.textAlignment = .center
            textField.tintColor = .clear //this will hide the cursor.
    
            return textField
        }()
    
        override func viewDidLoad() {
            super.viewDidLoad()
            textField.delegate = self
            //This sets the spacing or 'Kern' of the textfield. Adjust the value: 10.0 and the fontSize to get the desired output.
            textField.defaultTextAttributes.updateValue(10.0, forKey: NSAttributedStringKey.kern.rawValue)
        }
    }
    extension YourClass : UITextFieldDelegate {
            func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    
            //get the current text of the textField.
            guard let text = textField.text else { return false }
    
            //handle backspace event.
            if string == "" {
                guard let indexToReplace = text.index(text.startIndex, offsetBy: range.location, limitedBy: text.endIndex) else { return false }
                textField.text?.remove(at: indexToReplace)
                textField.text?.insert("—", at: indexToReplace)
                //adjust cursor position
                if let newPostion = textField.position(from: textField.beginningOfDocument, offset: range.location) {
                    textField.selectedTextRange = textField.textRange(from: newPostion, to: newPostion)
                    return false
                }
            }
            //handle character entered event.
            if range.location + 1 <= text.count,
                let end = text.index(text.startIndex, offsetBy: range.location + 1, limitedBy: text.endIndex),
                let start = text.index(text.startIndex, offsetBy: range.location, limitedBy: text.endIndex) {
                textField.text = textField.text?.replacingOccurrences(of: "—", with: string, options: .caseInsensitive, range: Range(uncheckedBounds: (lower: start, upper: end)))
            }
            //adjust cursor position.
            if range.location + 1 < text.count {
                if let newPosition = textField.position(from: textField.beginningOfDocument, offset: range.location + 1){
                    textField.selectedTextRange = textField.textRange(from: newPosition, to: newPosition)
                }
            }
            return false
        }
        //make sure to start at the begining of the textField.
        func textFieldDidBeginEditing(_ textField: UITextField) {
            let newPosition = textField.beginningOfDocument
            textField.selectedTextRange = textField.textRange(from: newPosition, to: newPosition)
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2018-02-13
      • 1970-01-01
      • 1970-01-01
      • 2013-10-21
      • 1970-01-01
      • 1970-01-01
      • 2018-12-30
      • 1970-01-01
      • 2023-03-12
      相关资源
      最近更新 更多