How to achieve that placeholder text disappears character by character in UITextField

后端 未结 6 1869
挽巷
挽巷 2021-02-18 20:28

Can you please help me.

In UITextField when we provide a placeholder text its placeholder string will be gone when we enter any character. How can I achieve

6条回答
  •  鱼传尺愫
    2021-02-18 21:23

    I don't believe the default behavior of the placeholder is editable, but what you are trying to accomplish can be done using NSAttributedString to simulate the placeholder value.

    I'm sure this can be optimized, but here I have created a handler class that acts as the delegate for a given UITextField, manipulating the string the user inputs to achieve the desired effect. You init the handler with your desired placeholder string, so you can make any text field work this way.

    import UIKit
    
    class CustomPlaceholderTextFieldHandler: NSObject {
        let placeholderText: String
        let placeholderAttributes = [NSForegroundColorAttributeName : UIColor.lightGray]
        let inputAttributes = [NSForegroundColorAttributeName : UIColor(red: 255/255, green: 153/255, blue: 0, alpha: 1.0)]
        var input = ""
    
        init(placeholder: String) {
            self.placeholderText = placeholder
            super.init()
        }
    
        func resetPlaceholder(for textField: UITextField) {
            input = ""
            setCombinedText(for: textField)
        }
    
        fileprivate func setCursorPosition(for textField: UITextField) {
            guard let cursorPosition = textField.position(from: textField.beginningOfDocument, offset: input.characters.count)
                else { return }
    
            textField.selectedTextRange = textField.textRange(from: cursorPosition, to: cursorPosition)
        }
    
        fileprivate func setCombinedText(for textField: UITextField) {
            let placeholderSubstring = placeholderText.substring(from: input.endIndex)
            let attributedString = NSMutableAttributedString(string: input + placeholderSubstring, attributes: placeholderAttributes)
            attributedString.addAttributes(inputAttributes, range: NSMakeRange(0, input.characters.count))
            textField.attributedText = attributedString
        }
    }
    
    extension CustomPlaceholderTextFieldHandler: UITextFieldDelegate {
        func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    
            if string == "" {
                if input.characters.count > 0 {
                    input = input.substring(to: input.index(before: input.endIndex))
                }
            } else {
                input += string
            }
    
            if input.characters.count <= placeholderText.characters.count {
                setCombinedText(for: textField)
                setCursorPosition(for: textField)
                return false
            }
            return true
        }
    
        func textFieldDidBeginEditing(_ textField: UITextField) {
            setCursorPosition(for: textField)
        }
    }
    

    Here's a the way I initialized the gif above:

    class ViewController: UIViewController {
    
        @IBOutlet weak var textField: UITextField!
        let placeholderHandler = CustomPlaceholderTextFieldHandler(placeholder: "_2_-__-__A")
    
        override func viewDidLoad() {
            super.viewDidLoad()
            textField.delegate = placeholderHandler
            placeholderHandler.resetPlaceholder(for: textField)
        }
    }
    

    This could be expanded to take color parameters, fonts, etc. at initialization, or you may find it cleaner to subclass UITextField and make it its own delegate. I also haven't really tested this for selecting/deleting/replacing multiple characters.

    The input variable will return the text the user has input at any given point. Also, using a fixed-width font would remove the jitteriness as the user types and replaces the placeholder text.

提交回复
热议问题